@keystrokehq/keystroke 0.1.98 → 0.1.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/agent-types.d.cts +2 -2
  2. package/dist/agent-types.d.mts +2 -2
  3. package/dist/agent.d.cts +3 -3
  4. package/dist/agent.d.mts +3 -3
  5. package/dist/client.cjs +11 -4
  6. package/dist/client.cjs.map +1 -1
  7. package/dist/client.mjs +11 -4
  8. package/dist/client.mjs.map +1 -1
  9. package/dist/dist-8vNmv_mW.cjs.map +1 -1
  10. package/dist/dist-BFKt0Zjj.mjs.map +1 -1
  11. package/dist/dist-CLfxDRUU.mjs.map +1 -1
  12. package/dist/dist-qx3gmcQl.cjs.map +1 -1
  13. package/dist/{index-bA2kvBPc.d.cts → index-BtUNie11.d.cts} +2 -2
  14. package/dist/{index-bA2kvBPc.d.cts.map → index-BtUNie11.d.cts.map} +1 -1
  15. package/dist/{index-CXcj7eqF.d.mts → index-CMNYHSVX.d.cts} +4 -4
  16. package/dist/{index-CXcj7eqF.d.mts.map → index-CMNYHSVX.d.cts.map} +1 -1
  17. package/dist/{index-h6WgSL7-.d.cts → index-CO_VO6lr.d.mts} +4 -4
  18. package/dist/{index-h6WgSL7-.d.cts.map → index-CO_VO6lr.d.mts.map} +1 -1
  19. package/dist/{index-EamQiIA4.d.mts → index-CtyhgvTK.d.mts} +2 -2
  20. package/dist/{index-EamQiIA4.d.mts.map → index-CtyhgvTK.d.mts.map} +1 -1
  21. package/dist/{index-g9zCnD1a.d.mts → index-CvogSqCs.d.mts} +4 -4
  22. package/dist/{index-g9zCnD1a.d.mts.map → index-CvogSqCs.d.mts.map} +1 -1
  23. package/dist/{index-CkRLIUAS.d.cts → index-DF9zc6h3.d.cts} +4 -4
  24. package/dist/{index-CkRLIUAS.d.cts.map → index-DF9zc6h3.d.cts.map} +1 -1
  25. package/dist/{schemas-1p0nmN8Z-BCN-nK9l.d.mts → schemas-1p0nmN8Z-BCMuzQbp.d.mts} +2 -2
  26. package/dist/{schemas-1p0nmN8Z-BCN-nK9l.d.mts.map → schemas-1p0nmN8Z-BCMuzQbp.d.mts.map} +1 -1
  27. package/dist/{schemas-1p0nmN8Z-DZojaQuV.d.cts → schemas-1p0nmN8Z-UP4_XT5s.d.cts} +2 -2
  28. package/dist/{schemas-1p0nmN8Z-DZojaQuV.d.cts.map → schemas-1p0nmN8Z-UP4_XT5s.d.cts.map} +1 -1
  29. package/dist/trigger.d.cts +1 -1
  30. package/dist/trigger.d.mts +1 -1
  31. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
1
  import { i as AgentToolUpdateCallback, n as AgentToolParameters, r as AgentToolResult, t as AgentTool } from "./index-CBVllUF5.cjs";
2
- import { a as UIMessage } from "./index-h6WgSL7-.cjs";
3
- import { a as AgentMessage, c as AgentPromptDiagnostics, d as AgentStreamEvent, g as ThinkingLevel, i as AgentEndEvent, l as AgentPromptFinishOutcome, t as AgentContextCompactedEvent, u as AgentStepStartEvent } from "./schemas-1p0nmN8Z-DZojaQuV.cjs";
2
+ import { a as UIMessage } from "./index-CMNYHSVX.cjs";
3
+ import { a as AgentMessage, c as AgentPromptDiagnostics, d as AgentStreamEvent, g as ThinkingLevel, i as AgentEndEvent, l as AgentPromptFinishOutcome, t as AgentContextCompactedEvent, u as AgentStepStartEvent } from "./schemas-1p0nmN8Z-UP4_XT5s.cjs";
4
4
  export { AgentContextCompactedEvent, AgentEndEvent, AgentMessage, AgentPromptDiagnostics, AgentPromptFinishOutcome, AgentStepStartEvent, AgentStreamEvent, type AgentTool, type AgentToolParameters, type AgentToolResult, type AgentToolUpdateCallback, ThinkingLevel, type UIMessage };
@@ -1,4 +1,4 @@
1
1
  import { i as AgentToolUpdateCallback, n as AgentToolParameters, r as AgentToolResult, t as AgentTool } from "./index-CBVllUF5.mjs";
2
- import { a as UIMessage } from "./index-CXcj7eqF.mjs";
3
- import { a as AgentMessage, c as AgentPromptDiagnostics, d as AgentStreamEvent, g as ThinkingLevel, i as AgentEndEvent, l as AgentPromptFinishOutcome, t as AgentContextCompactedEvent, u as AgentStepStartEvent } from "./schemas-1p0nmN8Z-BCN-nK9l.mjs";
2
+ import { a as UIMessage } from "./index-CO_VO6lr.mjs";
3
+ import { a as AgentMessage, c as AgentPromptDiagnostics, d as AgentStreamEvent, g as ThinkingLevel, i as AgentEndEvent, l as AgentPromptFinishOutcome, t as AgentContextCompactedEvent, u as AgentStepStartEvent } from "./schemas-1p0nmN8Z-BCMuzQbp.mjs";
4
4
  export { AgentContextCompactedEvent, AgentEndEvent, AgentMessage, AgentPromptDiagnostics, AgentPromptFinishOutcome, AgentStepStartEvent, AgentStreamEvent, type AgentTool, type AgentToolParameters, type AgentToolResult, type AgentToolUpdateCallback, ThinkingLevel, type UIMessage };
package/dist/agent.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { M as defineTool, P as modelSupportsMediaType, y as ModelCapabilities } from "./index-CBVllUF5.cjs";
2
- import { S as resolveThinkingLevel, _ as ThinkingLevelSchema, a as AgentMessage, b as resolveMaxSteps, c as AgentPromptDiagnostics, d as AgentStreamEvent, f as DEFAULT_COMPACTION_MODEL_ID, g as ThinkingLevel, m as DEFAULT_THINKING_LEVEL, n as AgentCreateInput, o as AgentModelId, p as DEFAULT_MAX_STEPS, r as AgentCreateInputSchema, s as AgentModelIdSchema, v as parseAgentCreateInput, x as resolveModelCapabilities, y as resolveAgentModel } from "./schemas-1p0nmN8Z-DZojaQuV.cjs";
3
- import { a as McpDefinitionInput, c as McpStdioOptions, d as McpTransport, f as connectMcpDefinition, g as isMcp, h as defineMcp, i as McpDefinition, l as McpStdioTransport, m as connectMcpStdio, n as McpAuthOptions, o as McpHttpTransport, p as connectMcpServer, r as McpClient, s as McpServerOptions, t as ToolCredentialResolver, u as McpToolConnection } from "./index-bA2kvBPc.cjs";
4
- import { A as currentLlmRunContext, B as resolveAgentId, C as StreamAgentPromptOptions, D as WebToolsOptions, E as UsageSinkEvent, F as isAgent, G as runLlm, H as resolveAgentWorkspaceRoot, I as isWithinAgentPromptExecution, J as validateAgentModelIds, K as streamAgentPrompt, L as normalizeAgentDefinition, M as finalStepText, N as getAgentPromptExecutionContext, O as agentModelIdsFromStoredManifest, P as hydrateChatAttachmentMessages, R as prepareAgentSession, S as SessionLifecycleContext, T as UsageSink, U as runAgentPrompt, V as resolveAgentTools, W as runDirectAgentPrompt, Y as withLlmRunContext, _ as ResolvedAgentAssets, a as AgentDefinition, b as SessionAgentMismatchError, c as AgentPromptExecutionContext, d as AgentToolInput, f as BuildAgentRuntimeContext, g as QueuedSubagentToolExecutor, h as PromptResponse, i as AgentChildToolContext, j as defineAgent, k as buildAgentRuntime, l as AgentRunConfig, m as PromptInput, n as Agent, o as AgentDefinitionInput, p as LlmRunContext, q as toSubagentTool, r as AgentAssetInput, s as AgentExperimentalDownload, t as AGENT, u as AgentStreamPort, v as RunAgentPromptOptions, w as StreamAgentPromptResult, x as SessionLifecycle, y as SandboxedAgentRuntime, z as resolveAgentAssets } from "./index-CkRLIUAS.cjs";
2
+ import { S as resolveThinkingLevel, _ as ThinkingLevelSchema, a as AgentMessage, b as resolveMaxSteps, c as AgentPromptDiagnostics, d as AgentStreamEvent, f as DEFAULT_COMPACTION_MODEL_ID, g as ThinkingLevel, m as DEFAULT_THINKING_LEVEL, n as AgentCreateInput, o as AgentModelId, p as DEFAULT_MAX_STEPS, r as AgentCreateInputSchema, s as AgentModelIdSchema, v as parseAgentCreateInput, x as resolveModelCapabilities, y as resolveAgentModel } from "./schemas-1p0nmN8Z-UP4_XT5s.cjs";
3
+ import { a as McpDefinitionInput, c as McpStdioOptions, d as McpTransport, f as connectMcpDefinition, g as isMcp, h as defineMcp, i as McpDefinition, l as McpStdioTransport, m as connectMcpStdio, n as McpAuthOptions, o as McpHttpTransport, p as connectMcpServer, r as McpClient, s as McpServerOptions, t as ToolCredentialResolver, u as McpToolConnection } from "./index-BtUNie11.cjs";
4
+ import { A as currentLlmRunContext, B as resolveAgentId, C as StreamAgentPromptOptions, D as WebToolsOptions, E as UsageSinkEvent, F as isAgent, G as runLlm, H as resolveAgentWorkspaceRoot, I as isWithinAgentPromptExecution, J as validateAgentModelIds, K as streamAgentPrompt, L as normalizeAgentDefinition, M as finalStepText, N as getAgentPromptExecutionContext, O as agentModelIdsFromStoredManifest, P as hydrateChatAttachmentMessages, R as prepareAgentSession, S as SessionLifecycleContext, T as UsageSink, U as runAgentPrompt, V as resolveAgentTools, W as runDirectAgentPrompt, Y as withLlmRunContext, _ as ResolvedAgentAssets, a as AgentDefinition, b as SessionAgentMismatchError, c as AgentPromptExecutionContext, d as AgentToolInput, f as BuildAgentRuntimeContext, g as QueuedSubagentToolExecutor, h as PromptResponse, i as AgentChildToolContext, j as defineAgent, k as buildAgentRuntime, l as AgentRunConfig, m as PromptInput, n as Agent, o as AgentDefinitionInput, p as LlmRunContext, q as toSubagentTool, r as AgentAssetInput, s as AgentExperimentalDownload, t as AGENT, u as AgentStreamPort, v as RunAgentPromptOptions, w as StreamAgentPromptResult, x as SessionLifecycle, y as SandboxedAgentRuntime, z as resolveAgentAssets } from "./index-DF9zc6h3.cjs";
5
5
  import { U as loadAssetManifest } from "./index-B_qytVTK.cjs";
6
6
  export { AGENT, type Agent, type AgentAssetInput, type AgentChildToolContext, type AgentCreateInput, AgentCreateInputSchema, type AgentDefinition, type AgentDefinitionInput, type AgentExperimentalDownload, type AgentMessage, type AgentModelId, AgentModelIdSchema, type AgentPromptDiagnostics, type AgentPromptExecutionContext, type AgentRunConfig, type AgentStreamEvent, type AgentStreamPort, type AgentToolInput, type BuildAgentRuntimeContext, DEFAULT_COMPACTION_MODEL_ID, DEFAULT_MAX_STEPS, DEFAULT_THINKING_LEVEL, type LlmRunContext, type McpAuthOptions, type McpClient, type McpDefinition, type McpDefinitionInput, type McpHttpTransport, type McpServerOptions, type McpStdioOptions, type McpStdioTransport, type McpToolConnection, type McpTransport, type ModelCapabilities, type PromptInput, type PromptResponse, type QueuedSubagentToolExecutor, type ResolvedAgentAssets, type RunAgentPromptOptions, type SandboxedAgentRuntime, SessionAgentMismatchError, type SessionLifecycle, type SessionLifecycleContext, type StreamAgentPromptOptions, type StreamAgentPromptResult, type ThinkingLevel, ThinkingLevelSchema, type ToolCredentialResolver, type UsageSink, type UsageSinkEvent, type WebToolsOptions, agentModelIdsFromStoredManifest, buildAgentRuntime, connectMcpDefinition, connectMcpServer, connectMcpStdio, currentLlmRunContext, defineAgent, defineMcp, defineTool, finalStepText, getAgentPromptExecutionContext, hydrateChatAttachmentMessages, isAgent, isMcp, isWithinAgentPromptExecution, loadAssetManifest, modelSupportsMediaType, normalizeAgentDefinition, parseAgentCreateInput, prepareAgentSession, resolveAgentAssets, resolveAgentId, resolveAgentModel, resolveAgentTools, resolveAgentWorkspaceRoot, resolveMaxSteps, resolveModelCapabilities, resolveThinkingLevel, runAgentPrompt, runDirectAgentPrompt, runLlm, streamAgentPrompt, toSubagentTool, validateAgentModelIds, withLlmRunContext };
package/dist/agent.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { M as defineTool, P as modelSupportsMediaType, y as ModelCapabilities } from "./index-CBVllUF5.mjs";
2
- import { S as resolveThinkingLevel, _ as ThinkingLevelSchema, a as AgentMessage, b as resolveMaxSteps, c as AgentPromptDiagnostics, d as AgentStreamEvent, f as DEFAULT_COMPACTION_MODEL_ID, g as ThinkingLevel, m as DEFAULT_THINKING_LEVEL, n as AgentCreateInput, o as AgentModelId, p as DEFAULT_MAX_STEPS, r as AgentCreateInputSchema, s as AgentModelIdSchema, v as parseAgentCreateInput, x as resolveModelCapabilities, y as resolveAgentModel } from "./schemas-1p0nmN8Z-BCN-nK9l.mjs";
3
- import { a as McpDefinitionInput, c as McpStdioOptions, d as McpTransport, f as connectMcpDefinition, g as isMcp, h as defineMcp, i as McpDefinition, l as McpStdioTransport, m as connectMcpStdio, n as McpAuthOptions, o as McpHttpTransport, p as connectMcpServer, r as McpClient, s as McpServerOptions, t as ToolCredentialResolver, u as McpToolConnection } from "./index-EamQiIA4.mjs";
4
- import { A as currentLlmRunContext, B as resolveAgentId, C as StreamAgentPromptOptions, D as WebToolsOptions, E as UsageSinkEvent, F as isAgent, G as runLlm, H as resolveAgentWorkspaceRoot, I as isWithinAgentPromptExecution, J as validateAgentModelIds, K as streamAgentPrompt, L as normalizeAgentDefinition, M as finalStepText, N as getAgentPromptExecutionContext, O as agentModelIdsFromStoredManifest, P as hydrateChatAttachmentMessages, R as prepareAgentSession, S as SessionLifecycleContext, T as UsageSink, U as runAgentPrompt, V as resolveAgentTools, W as runDirectAgentPrompt, Y as withLlmRunContext, _ as ResolvedAgentAssets, a as AgentDefinition, b as SessionAgentMismatchError, c as AgentPromptExecutionContext, d as AgentToolInput, f as BuildAgentRuntimeContext, g as QueuedSubagentToolExecutor, h as PromptResponse, i as AgentChildToolContext, j as defineAgent, k as buildAgentRuntime, l as AgentRunConfig, m as PromptInput, n as Agent, o as AgentDefinitionInput, p as LlmRunContext, q as toSubagentTool, r as AgentAssetInput, s as AgentExperimentalDownload, t as AGENT, u as AgentStreamPort, v as RunAgentPromptOptions, w as StreamAgentPromptResult, x as SessionLifecycle, y as SandboxedAgentRuntime, z as resolveAgentAssets } from "./index-g9zCnD1a.mjs";
2
+ import { S as resolveThinkingLevel, _ as ThinkingLevelSchema, a as AgentMessage, b as resolveMaxSteps, c as AgentPromptDiagnostics, d as AgentStreamEvent, f as DEFAULT_COMPACTION_MODEL_ID, g as ThinkingLevel, m as DEFAULT_THINKING_LEVEL, n as AgentCreateInput, o as AgentModelId, p as DEFAULT_MAX_STEPS, r as AgentCreateInputSchema, s as AgentModelIdSchema, v as parseAgentCreateInput, x as resolveModelCapabilities, y as resolveAgentModel } from "./schemas-1p0nmN8Z-BCMuzQbp.mjs";
3
+ import { a as McpDefinitionInput, c as McpStdioOptions, d as McpTransport, f as connectMcpDefinition, g as isMcp, h as defineMcp, i as McpDefinition, l as McpStdioTransport, m as connectMcpStdio, n as McpAuthOptions, o as McpHttpTransport, p as connectMcpServer, r as McpClient, s as McpServerOptions, t as ToolCredentialResolver, u as McpToolConnection } from "./index-CtyhgvTK.mjs";
4
+ import { A as currentLlmRunContext, B as resolveAgentId, C as StreamAgentPromptOptions, D as WebToolsOptions, E as UsageSinkEvent, F as isAgent, G as runLlm, H as resolveAgentWorkspaceRoot, I as isWithinAgentPromptExecution, J as validateAgentModelIds, K as streamAgentPrompt, L as normalizeAgentDefinition, M as finalStepText, N as getAgentPromptExecutionContext, O as agentModelIdsFromStoredManifest, P as hydrateChatAttachmentMessages, R as prepareAgentSession, S as SessionLifecycleContext, T as UsageSink, U as runAgentPrompt, V as resolveAgentTools, W as runDirectAgentPrompt, Y as withLlmRunContext, _ as ResolvedAgentAssets, a as AgentDefinition, b as SessionAgentMismatchError, c as AgentPromptExecutionContext, d as AgentToolInput, f as BuildAgentRuntimeContext, g as QueuedSubagentToolExecutor, h as PromptResponse, i as AgentChildToolContext, j as defineAgent, k as buildAgentRuntime, l as AgentRunConfig, m as PromptInput, n as Agent, o as AgentDefinitionInput, p as LlmRunContext, q as toSubagentTool, r as AgentAssetInput, s as AgentExperimentalDownload, t as AGENT, u as AgentStreamPort, v as RunAgentPromptOptions, w as StreamAgentPromptResult, x as SessionLifecycle, y as SandboxedAgentRuntime, z as resolveAgentAssets } from "./index-CvogSqCs.mjs";
5
5
  import { U as loadAssetManifest } from "./index-B8z6TmuK.mjs";
6
6
  export { AGENT, type Agent, type AgentAssetInput, type AgentChildToolContext, type AgentCreateInput, AgentCreateInputSchema, type AgentDefinition, type AgentDefinitionInput, type AgentExperimentalDownload, type AgentMessage, type AgentModelId, AgentModelIdSchema, type AgentPromptDiagnostics, type AgentPromptExecutionContext, type AgentRunConfig, type AgentStreamEvent, type AgentStreamPort, type AgentToolInput, type BuildAgentRuntimeContext, DEFAULT_COMPACTION_MODEL_ID, DEFAULT_MAX_STEPS, DEFAULT_THINKING_LEVEL, type LlmRunContext, type McpAuthOptions, type McpClient, type McpDefinition, type McpDefinitionInput, type McpHttpTransport, type McpServerOptions, type McpStdioOptions, type McpStdioTransport, type McpToolConnection, type McpTransport, type ModelCapabilities, type PromptInput, type PromptResponse, type QueuedSubagentToolExecutor, type ResolvedAgentAssets, type RunAgentPromptOptions, type SandboxedAgentRuntime, SessionAgentMismatchError, type SessionLifecycle, type SessionLifecycleContext, type StreamAgentPromptOptions, type StreamAgentPromptResult, type ThinkingLevel, ThinkingLevelSchema, type ToolCredentialResolver, type UsageSink, type UsageSinkEvent, type WebToolsOptions, agentModelIdsFromStoredManifest, buildAgentRuntime, connectMcpDefinition, connectMcpServer, connectMcpStdio, currentLlmRunContext, defineAgent, defineMcp, defineTool, finalStepText, getAgentPromptExecutionContext, hydrateChatAttachmentMessages, isAgent, isMcp, isWithinAgentPromptExecution, loadAssetManifest, modelSupportsMediaType, normalizeAgentDefinition, parseAgentCreateInput, prepareAgentSession, resolveAgentAssets, resolveAgentId, resolveAgentModel, resolveAgentTools, resolveAgentWorkspaceRoot, resolveMaxSteps, resolveModelCapabilities, resolveThinkingLevel, runAgentPrompt, runDirectAgentPrompt, runLlm, streamAgentPrompt, toSubagentTool, validateAgentModelIds, withLlmRunContext };
package/dist/client.cjs CHANGED
@@ -5,10 +5,17 @@ const require_dist$1 = require("./dist-C5j2jyOW.cjs");
5
5
  let ky = require("ky");
6
6
  ky = require_chunk.__toESM(ky, 1);
7
7
  //#region src/parse-mcp-execute-error.ts
8
- function throwMcpExecuteErrorFromBody(body, fallback) {
8
+ /**
9
+ * Throw an MCP execute failure with an HTTP status so telemetry treats
10
+ * upstream tool / argument failures (4xx, including 422) as expected.
11
+ * Callers must pass the response status — do not invent one.
12
+ */
13
+ function throwMcpExecuteErrorFromBody(body, fallback, status) {
9
14
  const parsed = require_dist.ExecuteKeystrokeToolErrorResponseSchema.safeParse(body);
10
- if (parsed.success) throw new Error(require_dist.formatMcpToolErrorMessage(parsed.data.message));
11
- throw new Error(fallback);
15
+ const message = parsed.success ? require_dist.formatMcpToolErrorMessage(parsed.data.message) : fallback;
16
+ const error = new Error(message);
17
+ error.status = status;
18
+ throw error;
12
19
  }
13
20
  //#endregion
14
21
  //#region src/client.ts
@@ -67,7 +74,7 @@ function createKeystrokeClient(options = {}) {
67
74
  throwHttpErrors: false
68
75
  });
69
76
  const body = await response.json();
70
- if (!response.ok) throwMcpExecuteErrorFromBody(typeof body === "object" && body !== null && ("error" in body || "message" in body) ? body : null, `MCP execute failed (${response.status})`);
77
+ if (!response.ok) throwMcpExecuteErrorFromBody(typeof body === "object" && body !== null && ("error" in body || "message" in body) ? body : null, `MCP execute failed (${response.status})`, response.status);
71
78
  return body;
72
79
  } } };
73
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.cjs","names":["ExecuteKeystrokeToolErrorResponseSchema","formatMcpToolErrorMessage","getRegisteredProjectScopeId","getRegisteredMcpCredentialContext"],"sources":["../src/parse-mcp-execute-error.ts","../src/client.ts"],"sourcesContent":["import {\n ExecuteKeystrokeToolErrorResponseSchema,\n formatMcpToolErrorMessage,\n} from \"@keystrokehq/shared\";\nimport { HTTPError } from \"ky\";\n\nexport async function throwParsedMcpExecuteHttpError(error: unknown): Promise<never> {\n if (error instanceof HTTPError) {\n const body = await error.response\n .clone()\n .json()\n .catch(() => null);\n throwMcpExecuteErrorFromBody(body, error.message);\n }\n\n throw error instanceof Error ? error : new Error(String(error));\n}\n\nexport function throwMcpExecuteErrorFromBody(body: unknown, fallback: string): never {\n const parsed = ExecuteKeystrokeToolErrorResponseSchema.safeParse(body);\n if (parsed.success) {\n throw new Error(formatMcpToolErrorMessage(parsed.data.message));\n }\n\n throw new Error(fallback);\n}\n","import {\n getRegisteredMcpCredentialContext,\n getRegisteredProjectScopeId,\n} from \"@keystrokehq/action\";\nimport ky, { type KyInstance, type Options } from \"ky\";\n\nimport { throwMcpExecuteErrorFromBody } from \"./parse-mcp-execute-error\";\n\nexport type KeystrokeClientOptions = {\n /** Defaults to process.env.KEYSTROKE_API_KEY */\n apiKey?: string;\n /** Defaults to PUBLIC_PLATFORM_URL, PLATFORM_URL, or http://localhost:3002 */\n platformUrl?: string;\n ky?: Options;\n};\n\ntype KeystrokeClientTarget = {\n executePath: string;\n headers: Record<string, string>;\n};\n\n/**\n * Workers run inside a container, so they must reach the platform via the internal\n * `PLATFORM_URL` (e.g. `host.docker.internal`); `PUBLIC_PLATFORM_URL` (e.g. `localhost`) is\n * only reachable from the host and would yield a connection error from inside the container.\n * The CLI runs on the host and prefers the public URL.\n */\nfunction resolveKeystrokePlatformUrl(\n options: KeystrokeClientOptions,\n preferInternal: boolean,\n): string {\n const candidates = preferInternal\n ? [options.platformUrl, process.env.PLATFORM_URL, process.env.PUBLIC_PLATFORM_URL]\n : [options.platformUrl, process.env.PUBLIC_PLATFORM_URL, process.env.PLATFORM_URL];\n return (candidates.find((url) => url) ?? \"http://localhost:3002\").replace(/\\/+$/, \"\");\n}\n\n/** Worker containers use PLATFORM_URL + /internal/projects/:id/mcp; CLI uses /mcp + org API key. */\nexport function resolveKeystrokeClientTarget(\n options: KeystrokeClientOptions = {},\n): KeystrokeClientTarget {\n const workerToken = process.env.WORKER_INTERNAL_TOKEN?.trim();\n const platformUrl = resolveKeystrokePlatformUrl(options, Boolean(workerToken));\n\n // The machine token identifies a worker. The project is the one bound for this run — the job\n // handler resolves it from the agent DB record (resolveAgentProjectId), binds it via\n // runWithProjectScope, and registers the getter so the facade reads it without importing\n // `@keystrokehq/database`. The platform resolves the credential instance server-side from\n // {app, project} (project → org). User-scoped creds require an explicit binding.\n if (workerToken) {\n const projectId = getRegisteredProjectScopeId() ?? \"default\";\n return {\n executePath: `${platformUrl}/internal/projects/${encodeURIComponent(projectId)}/mcp/execute`,\n headers: { Authorization: `Bearer ${workerToken}` },\n };\n }\n\n const apiKey = options.apiKey ?? process.env.KEYSTROKE_API_KEY;\n return {\n executePath: `${platformUrl}/mcp/execute`,\n headers: apiKey ? { \"x-api-key\": apiKey } : {},\n };\n}\n\nexport type ExecuteToolInput = {\n app: string;\n tool: string;\n arguments?: Record<string, unknown>;\n /** Pinned provider toolkit version (e.g. `20260501_01`); forwarded to the provider on execute. */\n version: string;\n};\n\nfunction buildExecutePayload(input: ExecuteToolInput) {\n const context = getRegisteredMcpCredentialContext();\n return {\n app: input.app,\n tool: input.tool,\n arguments: input.arguments ?? {},\n version: input.version,\n ...(context?.assignmentTarget ? { assignmentTarget: context.assignmentTarget } : {}),\n ...(context?.consumerId ? { consumerId: context.consumerId } : {}),\n };\n}\n\nexport type KeystrokeClient = {\n tools: {\n execute: (input: ExecuteToolInput) => Promise<{ ok: boolean; result: unknown }>;\n };\n};\n\nexport function createKeystrokeClient(options: KeystrokeClientOptions = {}): KeystrokeClient {\n const api: KyInstance = ky.create({\n ...options.ky,\n });\n\n return {\n tools: {\n execute: async (input) => {\n const target = resolveKeystrokeClientTarget(options);\n const response = await api.post(target.executePath, {\n headers: target.headers,\n json: buildExecutePayload(input),\n throwHttpErrors: false,\n });\n const body = (await response.json()) as\n | { ok: boolean; result: unknown }\n | { error?: string; message?: string };\n\n if (!response.ok) {\n const errorBody =\n typeof body === \"object\" && body !== null && (\"error\" in body || \"message\" in body)\n ? (body as { error?: string; message?: string })\n : null;\n throwMcpExecuteErrorFromBody(errorBody, `MCP execute failed (${response.status})`);\n }\n\n return body as { ok: boolean; result: unknown };\n },\n },\n };\n}\n"],"mappings":";;;;;;;AAkBA,SAAgB,6BAA6B,MAAe,UAAyB;CACnF,MAAM,SAASA,aAAAA,wCAAwC,UAAU,IAAI;CACrE,IAAI,OAAO,SACT,MAAM,IAAI,MAAMC,aAAAA,0BAA0B,OAAO,KAAK,OAAO,CAAC;CAGhE,MAAM,IAAI,MAAM,QAAQ;AAC1B;;;;;;;;;ACEA,SAAS,4BACP,SACA,gBACQ;CAIR,SAHmB,iBACf;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAc,QAAQ,IAAI;CAAmB,IAC/E;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAqB,QAAQ,IAAI;CAAY,GAChE,MAAM,QAAQ,GAAG,KAAK,yBAAyB,QAAQ,QAAQ,EAAE;AACtF;;AAGA,SAAgB,6BACd,UAAkC,CAAC,GACZ;CACvB,MAAM,cAAc,QAAQ,IAAI,uBAAuB,KAAK;CAC5D,MAAM,cAAc,4BAA4B,SAAS,QAAQ,WAAW,CAAC;CAO7E,IAAI,aAAa;EACf,MAAM,YAAYC,eAAAA,4BAA4B,KAAK;EACnD,OAAO;GACL,aAAa,GAAG,YAAY,qBAAqB,mBAAmB,SAAS,EAAE;GAC/E,SAAS,EAAE,eAAe,UAAU,cAAc;EACpD;CACF;CAEA,MAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;CAC7C,OAAO;EACL,aAAa,GAAG,YAAY;EAC5B,SAAS,SAAS,EAAE,aAAa,OAAO,IAAI,CAAC;CAC/C;AACF;AAUA,SAAS,oBAAoB,OAAyB;CACpD,MAAM,UAAUC,eAAAA,kCAAkC;CAClD,OAAO;EACL,KAAK,MAAM;EACX,MAAM,MAAM;EACZ,WAAW,MAAM,aAAa,CAAC;EAC/B,SAAS,MAAM;EACf,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,QAAQ,iBAAiB,IAAI,CAAC;EAClF,GAAI,SAAS,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;CAClE;AACF;AAQA,SAAgB,sBAAsB,UAAkC,CAAC,GAAoB;CAC3F,MAAM,MAAkB,GAAA,QAAG,OAAO,EAChC,GAAG,QAAQ,GACb,CAAC;CAED,OAAO,EACL,OAAO,EACL,SAAS,OAAO,UAAU;EACxB,MAAM,SAAS,6BAA6B,OAAO;EACnD,MAAM,WAAW,MAAM,IAAI,KAAK,OAAO,aAAa;GAClD,SAAS,OAAO;GAChB,MAAM,oBAAoB,KAAK;GAC/B,iBAAiB;EACnB,CAAC;EACD,MAAM,OAAQ,MAAM,SAAS,KAAK;EAIlC,IAAI,CAAC,SAAS,IAKZ,6BAHE,OAAO,SAAS,YAAY,SAAS,SAAS,WAAW,QAAQ,aAAa,QACzE,OACD,MACkC,uBAAuB,SAAS,OAAO,EAAE;EAGnF,OAAO;CACT,EACF,EACF;AACF"}
1
+ {"version":3,"file":"client.cjs","names":["ExecuteKeystrokeToolErrorResponseSchema","formatMcpToolErrorMessage","getRegisteredProjectScopeId","getRegisteredMcpCredentialContext"],"sources":["../src/parse-mcp-execute-error.ts","../src/client.ts"],"sourcesContent":["import {\n ExecuteKeystrokeToolErrorResponseSchema,\n formatMcpToolErrorMessage,\n} from \"@keystrokehq/shared\";\nimport { HTTPError } from \"ky\";\n\nexport async function throwParsedMcpExecuteHttpError(error: unknown): Promise<never> {\n if (error instanceof HTTPError) {\n const body = await error.response\n .clone()\n .json()\n .catch(() => null);\n throwMcpExecuteErrorFromBody(body, error.message, error.response.status);\n }\n\n throw error instanceof Error ? error : new Error(String(error));\n}\n\n/**\n * Throw an MCP execute failure with an HTTP status so telemetry treats\n * upstream tool / argument failures (4xx, including 422) as expected.\n * Callers must pass the response status — do not invent one.\n */\nexport function throwMcpExecuteErrorFromBody(\n body: unknown,\n fallback: string,\n status: number,\n): never {\n const parsed = ExecuteKeystrokeToolErrorResponseSchema.safeParse(body);\n const message = parsed.success ? formatMcpToolErrorMessage(parsed.data.message) : fallback;\n const error = new Error(message) as Error & { status: number };\n error.status = status;\n throw error;\n}\n","import {\n getRegisteredMcpCredentialContext,\n getRegisteredProjectScopeId,\n} from \"@keystrokehq/action\";\nimport ky, { type KyInstance, type Options } from \"ky\";\n\nimport { throwMcpExecuteErrorFromBody } from \"./parse-mcp-execute-error\";\n\nexport type KeystrokeClientOptions = {\n /** Defaults to process.env.KEYSTROKE_API_KEY */\n apiKey?: string;\n /** Defaults to PUBLIC_PLATFORM_URL, PLATFORM_URL, or http://localhost:3002 */\n platformUrl?: string;\n ky?: Options;\n};\n\ntype KeystrokeClientTarget = {\n executePath: string;\n headers: Record<string, string>;\n};\n\n/**\n * Workers run inside a container, so they must reach the platform via the internal\n * `PLATFORM_URL` (e.g. `host.docker.internal`); `PUBLIC_PLATFORM_URL` (e.g. `localhost`) is\n * only reachable from the host and would yield a connection error from inside the container.\n * The CLI runs on the host and prefers the public URL.\n */\nfunction resolveKeystrokePlatformUrl(\n options: KeystrokeClientOptions,\n preferInternal: boolean,\n): string {\n const candidates = preferInternal\n ? [options.platformUrl, process.env.PLATFORM_URL, process.env.PUBLIC_PLATFORM_URL]\n : [options.platformUrl, process.env.PUBLIC_PLATFORM_URL, process.env.PLATFORM_URL];\n return (candidates.find((url) => url) ?? \"http://localhost:3002\").replace(/\\/+$/, \"\");\n}\n\n/** Worker containers use PLATFORM_URL + /internal/projects/:id/mcp; CLI uses /mcp + org API key. */\nexport function resolveKeystrokeClientTarget(\n options: KeystrokeClientOptions = {},\n): KeystrokeClientTarget {\n const workerToken = process.env.WORKER_INTERNAL_TOKEN?.trim();\n const platformUrl = resolveKeystrokePlatformUrl(options, Boolean(workerToken));\n\n // The machine token identifies a worker. The project is the one bound for this run — the job\n // handler resolves it from the agent DB record (resolveAgentProjectId), binds it via\n // runWithProjectScope, and registers the getter so the facade reads it without importing\n // `@keystrokehq/database`. The platform resolves the credential instance server-side from\n // {app, project} (project → org). User-scoped creds require an explicit binding.\n if (workerToken) {\n const projectId = getRegisteredProjectScopeId() ?? \"default\";\n return {\n executePath: `${platformUrl}/internal/projects/${encodeURIComponent(projectId)}/mcp/execute`,\n headers: { Authorization: `Bearer ${workerToken}` },\n };\n }\n\n const apiKey = options.apiKey ?? process.env.KEYSTROKE_API_KEY;\n return {\n executePath: `${platformUrl}/mcp/execute`,\n headers: apiKey ? { \"x-api-key\": apiKey } : {},\n };\n}\n\nexport type ExecuteToolInput = {\n app: string;\n tool: string;\n arguments?: Record<string, unknown>;\n /** Pinned provider toolkit version (e.g. `20260501_01`); forwarded to the provider on execute. */\n version: string;\n};\n\nfunction buildExecutePayload(input: ExecuteToolInput) {\n const context = getRegisteredMcpCredentialContext();\n return {\n app: input.app,\n tool: input.tool,\n arguments: input.arguments ?? {},\n version: input.version,\n ...(context?.assignmentTarget ? { assignmentTarget: context.assignmentTarget } : {}),\n ...(context?.consumerId ? { consumerId: context.consumerId } : {}),\n };\n}\n\nexport type KeystrokeClient = {\n tools: {\n execute: (input: ExecuteToolInput) => Promise<{ ok: boolean; result: unknown }>;\n };\n};\n\nexport function createKeystrokeClient(options: KeystrokeClientOptions = {}): KeystrokeClient {\n const api: KyInstance = ky.create({\n ...options.ky,\n });\n\n return {\n tools: {\n execute: async (input) => {\n const target = resolveKeystrokeClientTarget(options);\n const response = await api.post(target.executePath, {\n headers: target.headers,\n json: buildExecutePayload(input),\n throwHttpErrors: false,\n });\n const body = (await response.json()) as\n | { ok: boolean; result: unknown }\n | { error?: string; message?: string };\n\n if (!response.ok) {\n const errorBody =\n typeof body === \"object\" && body !== null && (\"error\" in body || \"message\" in body)\n ? (body as { error?: string; message?: string })\n : null;\n throwMcpExecuteErrorFromBody(\n errorBody,\n `MCP execute failed (${response.status})`,\n response.status,\n );\n }\n\n return body as { ok: boolean; result: unknown };\n },\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;AAuBA,SAAgB,6BACd,MACA,UACA,QACO;CACP,MAAM,SAASA,aAAAA,wCAAwC,UAAU,IAAI;CACrE,MAAM,UAAU,OAAO,UAAUC,aAAAA,0BAA0B,OAAO,KAAK,OAAO,IAAI;CAClF,MAAM,QAAQ,IAAI,MAAM,OAAO;CAC/B,MAAM,SAAS;CACf,MAAM;AACR;;;;;;;;;ACNA,SAAS,4BACP,SACA,gBACQ;CAIR,SAHmB,iBACf;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAc,QAAQ,IAAI;CAAmB,IAC/E;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAqB,QAAQ,IAAI;CAAY,GAChE,MAAM,QAAQ,GAAG,KAAK,yBAAyB,QAAQ,QAAQ,EAAE;AACtF;;AAGA,SAAgB,6BACd,UAAkC,CAAC,GACZ;CACvB,MAAM,cAAc,QAAQ,IAAI,uBAAuB,KAAK;CAC5D,MAAM,cAAc,4BAA4B,SAAS,QAAQ,WAAW,CAAC;CAO7E,IAAI,aAAa;EACf,MAAM,YAAYC,eAAAA,4BAA4B,KAAK;EACnD,OAAO;GACL,aAAa,GAAG,YAAY,qBAAqB,mBAAmB,SAAS,EAAE;GAC/E,SAAS,EAAE,eAAe,UAAU,cAAc;EACpD;CACF;CAEA,MAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;CAC7C,OAAO;EACL,aAAa,GAAG,YAAY;EAC5B,SAAS,SAAS,EAAE,aAAa,OAAO,IAAI,CAAC;CAC/C;AACF;AAUA,SAAS,oBAAoB,OAAyB;CACpD,MAAM,UAAUC,eAAAA,kCAAkC;CAClD,OAAO;EACL,KAAK,MAAM;EACX,MAAM,MAAM;EACZ,WAAW,MAAM,aAAa,CAAC;EAC/B,SAAS,MAAM;EACf,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,QAAQ,iBAAiB,IAAI,CAAC;EAClF,GAAI,SAAS,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;CAClE;AACF;AAQA,SAAgB,sBAAsB,UAAkC,CAAC,GAAoB;CAC3F,MAAM,MAAkB,GAAA,QAAG,OAAO,EAChC,GAAG,QAAQ,GACb,CAAC;CAED,OAAO,EACL,OAAO,EACL,SAAS,OAAO,UAAU;EACxB,MAAM,SAAS,6BAA6B,OAAO;EACnD,MAAM,WAAW,MAAM,IAAI,KAAK,OAAO,aAAa;GAClD,SAAS,OAAO;GAChB,MAAM,oBAAoB,KAAK;GAC/B,iBAAiB;EACnB,CAAC;EACD,MAAM,OAAQ,MAAM,SAAS,KAAK;EAIlC,IAAI,CAAC,SAAS,IAKZ,6BAHE,OAAO,SAAS,YAAY,SAAS,SAAS,WAAW,QAAQ,aAAa,QACzE,OACD,MAGJ,uBAAuB,SAAS,OAAO,IACvC,SAAS,MACX;EAGF,OAAO;CACT,EACF,EACF;AACF"}
package/dist/client.mjs CHANGED
@@ -2,10 +2,17 @@ import { i as ExecuteKeystrokeToolErrorResponseSchema, v as formatMcpToolErrorMe
2
2
  import { o as getRegisteredMcpCredentialContext, s as getRegisteredProjectScopeId } from "./dist-CnZvvup3.mjs";
3
3
  import ky from "ky";
4
4
  //#region src/parse-mcp-execute-error.ts
5
- function throwMcpExecuteErrorFromBody(body, fallback) {
5
+ /**
6
+ * Throw an MCP execute failure with an HTTP status so telemetry treats
7
+ * upstream tool / argument failures (4xx, including 422) as expected.
8
+ * Callers must pass the response status — do not invent one.
9
+ */
10
+ function throwMcpExecuteErrorFromBody(body, fallback, status) {
6
11
  const parsed = ExecuteKeystrokeToolErrorResponseSchema.safeParse(body);
7
- if (parsed.success) throw new Error(formatMcpToolErrorMessage(parsed.data.message));
8
- throw new Error(fallback);
12
+ const message = parsed.success ? formatMcpToolErrorMessage(parsed.data.message) : fallback;
13
+ const error = new Error(message);
14
+ error.status = status;
15
+ throw error;
9
16
  }
10
17
  //#endregion
11
18
  //#region src/client.ts
@@ -64,7 +71,7 @@ function createKeystrokeClient(options = {}) {
64
71
  throwHttpErrors: false
65
72
  });
66
73
  const body = await response.json();
67
- if (!response.ok) throwMcpExecuteErrorFromBody(typeof body === "object" && body !== null && ("error" in body || "message" in body) ? body : null, `MCP execute failed (${response.status})`);
74
+ if (!response.ok) throwMcpExecuteErrorFromBody(typeof body === "object" && body !== null && ("error" in body || "message" in body) ? body : null, `MCP execute failed (${response.status})`, response.status);
68
75
  return body;
69
76
  } } };
70
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":[],"sources":["../src/parse-mcp-execute-error.ts","../src/client.ts"],"sourcesContent":["import {\n ExecuteKeystrokeToolErrorResponseSchema,\n formatMcpToolErrorMessage,\n} from \"@keystrokehq/shared\";\nimport { HTTPError } from \"ky\";\n\nexport async function throwParsedMcpExecuteHttpError(error: unknown): Promise<never> {\n if (error instanceof HTTPError) {\n const body = await error.response\n .clone()\n .json()\n .catch(() => null);\n throwMcpExecuteErrorFromBody(body, error.message);\n }\n\n throw error instanceof Error ? error : new Error(String(error));\n}\n\nexport function throwMcpExecuteErrorFromBody(body: unknown, fallback: string): never {\n const parsed = ExecuteKeystrokeToolErrorResponseSchema.safeParse(body);\n if (parsed.success) {\n throw new Error(formatMcpToolErrorMessage(parsed.data.message));\n }\n\n throw new Error(fallback);\n}\n","import {\n getRegisteredMcpCredentialContext,\n getRegisteredProjectScopeId,\n} from \"@keystrokehq/action\";\nimport ky, { type KyInstance, type Options } from \"ky\";\n\nimport { throwMcpExecuteErrorFromBody } from \"./parse-mcp-execute-error\";\n\nexport type KeystrokeClientOptions = {\n /** Defaults to process.env.KEYSTROKE_API_KEY */\n apiKey?: string;\n /** Defaults to PUBLIC_PLATFORM_URL, PLATFORM_URL, or http://localhost:3002 */\n platformUrl?: string;\n ky?: Options;\n};\n\ntype KeystrokeClientTarget = {\n executePath: string;\n headers: Record<string, string>;\n};\n\n/**\n * Workers run inside a container, so they must reach the platform via the internal\n * `PLATFORM_URL` (e.g. `host.docker.internal`); `PUBLIC_PLATFORM_URL` (e.g. `localhost`) is\n * only reachable from the host and would yield a connection error from inside the container.\n * The CLI runs on the host and prefers the public URL.\n */\nfunction resolveKeystrokePlatformUrl(\n options: KeystrokeClientOptions,\n preferInternal: boolean,\n): string {\n const candidates = preferInternal\n ? [options.platformUrl, process.env.PLATFORM_URL, process.env.PUBLIC_PLATFORM_URL]\n : [options.platformUrl, process.env.PUBLIC_PLATFORM_URL, process.env.PLATFORM_URL];\n return (candidates.find((url) => url) ?? \"http://localhost:3002\").replace(/\\/+$/, \"\");\n}\n\n/** Worker containers use PLATFORM_URL + /internal/projects/:id/mcp; CLI uses /mcp + org API key. */\nexport function resolveKeystrokeClientTarget(\n options: KeystrokeClientOptions = {},\n): KeystrokeClientTarget {\n const workerToken = process.env.WORKER_INTERNAL_TOKEN?.trim();\n const platformUrl = resolveKeystrokePlatformUrl(options, Boolean(workerToken));\n\n // The machine token identifies a worker. The project is the one bound for this run — the job\n // handler resolves it from the agent DB record (resolveAgentProjectId), binds it via\n // runWithProjectScope, and registers the getter so the facade reads it without importing\n // `@keystrokehq/database`. The platform resolves the credential instance server-side from\n // {app, project} (project → org). User-scoped creds require an explicit binding.\n if (workerToken) {\n const projectId = getRegisteredProjectScopeId() ?? \"default\";\n return {\n executePath: `${platformUrl}/internal/projects/${encodeURIComponent(projectId)}/mcp/execute`,\n headers: { Authorization: `Bearer ${workerToken}` },\n };\n }\n\n const apiKey = options.apiKey ?? process.env.KEYSTROKE_API_KEY;\n return {\n executePath: `${platformUrl}/mcp/execute`,\n headers: apiKey ? { \"x-api-key\": apiKey } : {},\n };\n}\n\nexport type ExecuteToolInput = {\n app: string;\n tool: string;\n arguments?: Record<string, unknown>;\n /** Pinned provider toolkit version (e.g. `20260501_01`); forwarded to the provider on execute. */\n version: string;\n};\n\nfunction buildExecutePayload(input: ExecuteToolInput) {\n const context = getRegisteredMcpCredentialContext();\n return {\n app: input.app,\n tool: input.tool,\n arguments: input.arguments ?? {},\n version: input.version,\n ...(context?.assignmentTarget ? { assignmentTarget: context.assignmentTarget } : {}),\n ...(context?.consumerId ? { consumerId: context.consumerId } : {}),\n };\n}\n\nexport type KeystrokeClient = {\n tools: {\n execute: (input: ExecuteToolInput) => Promise<{ ok: boolean; result: unknown }>;\n };\n};\n\nexport function createKeystrokeClient(options: KeystrokeClientOptions = {}): KeystrokeClient {\n const api: KyInstance = ky.create({\n ...options.ky,\n });\n\n return {\n tools: {\n execute: async (input) => {\n const target = resolveKeystrokeClientTarget(options);\n const response = await api.post(target.executePath, {\n headers: target.headers,\n json: buildExecutePayload(input),\n throwHttpErrors: false,\n });\n const body = (await response.json()) as\n | { ok: boolean; result: unknown }\n | { error?: string; message?: string };\n\n if (!response.ok) {\n const errorBody =\n typeof body === \"object\" && body !== null && (\"error\" in body || \"message\" in body)\n ? (body as { error?: string; message?: string })\n : null;\n throwMcpExecuteErrorFromBody(errorBody, `MCP execute failed (${response.status})`);\n }\n\n return body as { ok: boolean; result: unknown };\n },\n },\n };\n}\n"],"mappings":";;;;AAkBA,SAAgB,6BAA6B,MAAe,UAAyB;CACnF,MAAM,SAAS,wCAAwC,UAAU,IAAI;CACrE,IAAI,OAAO,SACT,MAAM,IAAI,MAAM,0BAA0B,OAAO,KAAK,OAAO,CAAC;CAGhE,MAAM,IAAI,MAAM,QAAQ;AAC1B;;;;;;;;;ACEA,SAAS,4BACP,SACA,gBACQ;CAIR,SAHmB,iBACf;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAc,QAAQ,IAAI;CAAmB,IAC/E;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAqB,QAAQ,IAAI;CAAY,GAChE,MAAM,QAAQ,GAAG,KAAK,yBAAyB,QAAQ,QAAQ,EAAE;AACtF;;AAGA,SAAgB,6BACd,UAAkC,CAAC,GACZ;CACvB,MAAM,cAAc,QAAQ,IAAI,uBAAuB,KAAK;CAC5D,MAAM,cAAc,4BAA4B,SAAS,QAAQ,WAAW,CAAC;CAO7E,IAAI,aAAa;EACf,MAAM,YAAY,4BAA4B,KAAK;EACnD,OAAO;GACL,aAAa,GAAG,YAAY,qBAAqB,mBAAmB,SAAS,EAAE;GAC/E,SAAS,EAAE,eAAe,UAAU,cAAc;EACpD;CACF;CAEA,MAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;CAC7C,OAAO;EACL,aAAa,GAAG,YAAY;EAC5B,SAAS,SAAS,EAAE,aAAa,OAAO,IAAI,CAAC;CAC/C;AACF;AAUA,SAAS,oBAAoB,OAAyB;CACpD,MAAM,UAAU,kCAAkC;CAClD,OAAO;EACL,KAAK,MAAM;EACX,MAAM,MAAM;EACZ,WAAW,MAAM,aAAa,CAAC;EAC/B,SAAS,MAAM;EACf,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,QAAQ,iBAAiB,IAAI,CAAC;EAClF,GAAI,SAAS,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;CAClE;AACF;AAQA,SAAgB,sBAAsB,UAAkC,CAAC,GAAoB;CAC3F,MAAM,MAAkB,GAAG,OAAO,EAChC,GAAG,QAAQ,GACb,CAAC;CAED,OAAO,EACL,OAAO,EACL,SAAS,OAAO,UAAU;EACxB,MAAM,SAAS,6BAA6B,OAAO;EACnD,MAAM,WAAW,MAAM,IAAI,KAAK,OAAO,aAAa;GAClD,SAAS,OAAO;GAChB,MAAM,oBAAoB,KAAK;GAC/B,iBAAiB;EACnB,CAAC;EACD,MAAM,OAAQ,MAAM,SAAS,KAAK;EAIlC,IAAI,CAAC,SAAS,IAKZ,6BAHE,OAAO,SAAS,YAAY,SAAS,SAAS,WAAW,QAAQ,aAAa,QACzE,OACD,MACkC,uBAAuB,SAAS,OAAO,EAAE;EAGnF,OAAO;CACT,EACF,EACF;AACF"}
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../src/parse-mcp-execute-error.ts","../src/client.ts"],"sourcesContent":["import {\n ExecuteKeystrokeToolErrorResponseSchema,\n formatMcpToolErrorMessage,\n} from \"@keystrokehq/shared\";\nimport { HTTPError } from \"ky\";\n\nexport async function throwParsedMcpExecuteHttpError(error: unknown): Promise<never> {\n if (error instanceof HTTPError) {\n const body = await error.response\n .clone()\n .json()\n .catch(() => null);\n throwMcpExecuteErrorFromBody(body, error.message, error.response.status);\n }\n\n throw error instanceof Error ? error : new Error(String(error));\n}\n\n/**\n * Throw an MCP execute failure with an HTTP status so telemetry treats\n * upstream tool / argument failures (4xx, including 422) as expected.\n * Callers must pass the response status — do not invent one.\n */\nexport function throwMcpExecuteErrorFromBody(\n body: unknown,\n fallback: string,\n status: number,\n): never {\n const parsed = ExecuteKeystrokeToolErrorResponseSchema.safeParse(body);\n const message = parsed.success ? formatMcpToolErrorMessage(parsed.data.message) : fallback;\n const error = new Error(message) as Error & { status: number };\n error.status = status;\n throw error;\n}\n","import {\n getRegisteredMcpCredentialContext,\n getRegisteredProjectScopeId,\n} from \"@keystrokehq/action\";\nimport ky, { type KyInstance, type Options } from \"ky\";\n\nimport { throwMcpExecuteErrorFromBody } from \"./parse-mcp-execute-error\";\n\nexport type KeystrokeClientOptions = {\n /** Defaults to process.env.KEYSTROKE_API_KEY */\n apiKey?: string;\n /** Defaults to PUBLIC_PLATFORM_URL, PLATFORM_URL, or http://localhost:3002 */\n platformUrl?: string;\n ky?: Options;\n};\n\ntype KeystrokeClientTarget = {\n executePath: string;\n headers: Record<string, string>;\n};\n\n/**\n * Workers run inside a container, so they must reach the platform via the internal\n * `PLATFORM_URL` (e.g. `host.docker.internal`); `PUBLIC_PLATFORM_URL` (e.g. `localhost`) is\n * only reachable from the host and would yield a connection error from inside the container.\n * The CLI runs on the host and prefers the public URL.\n */\nfunction resolveKeystrokePlatformUrl(\n options: KeystrokeClientOptions,\n preferInternal: boolean,\n): string {\n const candidates = preferInternal\n ? [options.platformUrl, process.env.PLATFORM_URL, process.env.PUBLIC_PLATFORM_URL]\n : [options.platformUrl, process.env.PUBLIC_PLATFORM_URL, process.env.PLATFORM_URL];\n return (candidates.find((url) => url) ?? \"http://localhost:3002\").replace(/\\/+$/, \"\");\n}\n\n/** Worker containers use PLATFORM_URL + /internal/projects/:id/mcp; CLI uses /mcp + org API key. */\nexport function resolveKeystrokeClientTarget(\n options: KeystrokeClientOptions = {},\n): KeystrokeClientTarget {\n const workerToken = process.env.WORKER_INTERNAL_TOKEN?.trim();\n const platformUrl = resolveKeystrokePlatformUrl(options, Boolean(workerToken));\n\n // The machine token identifies a worker. The project is the one bound for this run — the job\n // handler resolves it from the agent DB record (resolveAgentProjectId), binds it via\n // runWithProjectScope, and registers the getter so the facade reads it without importing\n // `@keystrokehq/database`. The platform resolves the credential instance server-side from\n // {app, project} (project → org). User-scoped creds require an explicit binding.\n if (workerToken) {\n const projectId = getRegisteredProjectScopeId() ?? \"default\";\n return {\n executePath: `${platformUrl}/internal/projects/${encodeURIComponent(projectId)}/mcp/execute`,\n headers: { Authorization: `Bearer ${workerToken}` },\n };\n }\n\n const apiKey = options.apiKey ?? process.env.KEYSTROKE_API_KEY;\n return {\n executePath: `${platformUrl}/mcp/execute`,\n headers: apiKey ? { \"x-api-key\": apiKey } : {},\n };\n}\n\nexport type ExecuteToolInput = {\n app: string;\n tool: string;\n arguments?: Record<string, unknown>;\n /** Pinned provider toolkit version (e.g. `20260501_01`); forwarded to the provider on execute. */\n version: string;\n};\n\nfunction buildExecutePayload(input: ExecuteToolInput) {\n const context = getRegisteredMcpCredentialContext();\n return {\n app: input.app,\n tool: input.tool,\n arguments: input.arguments ?? {},\n version: input.version,\n ...(context?.assignmentTarget ? { assignmentTarget: context.assignmentTarget } : {}),\n ...(context?.consumerId ? { consumerId: context.consumerId } : {}),\n };\n}\n\nexport type KeystrokeClient = {\n tools: {\n execute: (input: ExecuteToolInput) => Promise<{ ok: boolean; result: unknown }>;\n };\n};\n\nexport function createKeystrokeClient(options: KeystrokeClientOptions = {}): KeystrokeClient {\n const api: KyInstance = ky.create({\n ...options.ky,\n });\n\n return {\n tools: {\n execute: async (input) => {\n const target = resolveKeystrokeClientTarget(options);\n const response = await api.post(target.executePath, {\n headers: target.headers,\n json: buildExecutePayload(input),\n throwHttpErrors: false,\n });\n const body = (await response.json()) as\n | { ok: boolean; result: unknown }\n | { error?: string; message?: string };\n\n if (!response.ok) {\n const errorBody =\n typeof body === \"object\" && body !== null && (\"error\" in body || \"message\" in body)\n ? (body as { error?: string; message?: string })\n : null;\n throwMcpExecuteErrorFromBody(\n errorBody,\n `MCP execute failed (${response.status})`,\n response.status,\n );\n }\n\n return body as { ok: boolean; result: unknown };\n },\n },\n };\n}\n"],"mappings":";;;;;;;;;AAuBA,SAAgB,6BACd,MACA,UACA,QACO;CACP,MAAM,SAAS,wCAAwC,UAAU,IAAI;CACrE,MAAM,UAAU,OAAO,UAAU,0BAA0B,OAAO,KAAK,OAAO,IAAI;CAClF,MAAM,QAAQ,IAAI,MAAM,OAAO;CAC/B,MAAM,SAAS;CACf,MAAM;AACR;;;;;;;;;ACNA,SAAS,4BACP,SACA,gBACQ;CAIR,SAHmB,iBACf;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAc,QAAQ,IAAI;CAAmB,IAC/E;EAAC,QAAQ;EAAa,QAAQ,IAAI;EAAqB,QAAQ,IAAI;CAAY,GAChE,MAAM,QAAQ,GAAG,KAAK,yBAAyB,QAAQ,QAAQ,EAAE;AACtF;;AAGA,SAAgB,6BACd,UAAkC,CAAC,GACZ;CACvB,MAAM,cAAc,QAAQ,IAAI,uBAAuB,KAAK;CAC5D,MAAM,cAAc,4BAA4B,SAAS,QAAQ,WAAW,CAAC;CAO7E,IAAI,aAAa;EACf,MAAM,YAAY,4BAA4B,KAAK;EACnD,OAAO;GACL,aAAa,GAAG,YAAY,qBAAqB,mBAAmB,SAAS,EAAE;GAC/E,SAAS,EAAE,eAAe,UAAU,cAAc;EACpD;CACF;CAEA,MAAM,SAAS,QAAQ,UAAU,QAAQ,IAAI;CAC7C,OAAO;EACL,aAAa,GAAG,YAAY;EAC5B,SAAS,SAAS,EAAE,aAAa,OAAO,IAAI,CAAC;CAC/C;AACF;AAUA,SAAS,oBAAoB,OAAyB;CACpD,MAAM,UAAU,kCAAkC;CAClD,OAAO;EACL,KAAK,MAAM;EACX,MAAM,MAAM;EACZ,WAAW,MAAM,aAAa,CAAC;EAC/B,SAAS,MAAM;EACf,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,QAAQ,iBAAiB,IAAI,CAAC;EAClF,GAAI,SAAS,aAAa,EAAE,YAAY,QAAQ,WAAW,IAAI,CAAC;CAClE;AACF;AAQA,SAAgB,sBAAsB,UAAkC,CAAC,GAAoB;CAC3F,MAAM,MAAkB,GAAG,OAAO,EAChC,GAAG,QAAQ,GACb,CAAC;CAED,OAAO,EACL,OAAO,EACL,SAAS,OAAO,UAAU;EACxB,MAAM,SAAS,6BAA6B,OAAO;EACnD,MAAM,WAAW,MAAM,IAAI,KAAK,OAAO,aAAa;GAClD,SAAS,OAAO;GAChB,MAAM,oBAAoB,KAAK;GAC/B,iBAAiB;EACnB,CAAC;EACD,MAAM,OAAQ,MAAM,SAAS,KAAK;EAIlC,IAAI,CAAC,SAAS,IAKZ,6BAHE,OAAO,SAAS,YAAY,SAAS,SAAS,WAAW,QAAQ,aAAa,QACzE,OACD,MAGJ,uBAAuB,SAAS,OAAO,IACvC,SAAS,MACX;EAGF,OAAO;CACT,EACF,EACF;AACF"}