@runlayer/hooks-sdk 0.1.0

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 (42) hide show
  1. package/README.md +292 -0
  2. package/dist/claude-agent-sdk.d.ts +43 -0
  3. package/dist/claude-agent-sdk.d.ts.map +1 -0
  4. package/dist/claude-agent-sdk.js +202 -0
  5. package/dist/claude-agent-sdk.js.map +1 -0
  6. package/dist/client.d.ts +142 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +536 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/google-adk.d.ts +26 -0
  11. package/dist/google-adk.d.ts.map +1 -0
  12. package/dist/google-adk.js +33 -0
  13. package/dist/google-adk.js.map +1 -0
  14. package/dist/index.d.ts +15 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +8 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/internal.d.ts +4 -0
  19. package/dist/internal.d.ts.map +1 -0
  20. package/dist/internal.js +4 -0
  21. package/dist/internal.js.map +1 -0
  22. package/dist/openai-agents-sdk.d.ts +28 -0
  23. package/dist/openai-agents-sdk.d.ts.map +1 -0
  24. package/dist/openai-agents-sdk.js +31 -0
  25. package/dist/openai-agents-sdk.js.map +1 -0
  26. package/dist/preflight.d.ts +14 -0
  27. package/dist/preflight.d.ts.map +1 -0
  28. package/dist/preflight.js +35 -0
  29. package/dist/preflight.js.map +1 -0
  30. package/dist/tool-adapter.d.ts +29 -0
  31. package/dist/tool-adapter.d.ts.map +1 -0
  32. package/dist/tool-adapter.js +61 -0
  33. package/dist/tool-adapter.js.map +1 -0
  34. package/dist/tool-enforcement.d.ts +18 -0
  35. package/dist/tool-enforcement.d.ts.map +1 -0
  36. package/dist/tool-enforcement.js +114 -0
  37. package/dist/tool-enforcement.js.map +1 -0
  38. package/dist/vercel-ai-sdk.d.ts +20 -0
  39. package/dist/vercel-ai-sdk.d.ts.map +1 -0
  40. package/dist/vercel-ai-sdk.js +29 -0
  41. package/dist/vercel-ai-sdk.js.map +1 -0
  42. package/package.json +68 -0
package/README.md ADDED
@@ -0,0 +1,292 @@
1
+ # Runlayer Hooks TypeScript SDK
2
+
3
+ First-party Hooks TypeScript SDK for wiring agent runtimes into Runlayer governance,
4
+ telemetry, and hook enforcement.
5
+
6
+ Phase 1 supports Claude Agent SDK hooks plus structural adapters for common
7
+ TypeScript agent tool APIs:
8
+
9
+ - lifecycle telemetry for session, prompt, and stop events
10
+ - pre-tool enforcement with argument rewriting
11
+ - post-tool output scanning and blocking
12
+ - failed tool telemetry
13
+ - direct MCP source enforcement
14
+ - preflight session emission for ingestion checks
15
+ - transcript-bearing `Stop` emission for completed assistant messages
16
+ - Vercel AI SDK tool wrappers
17
+ - OpenAI Agents SDK function tool wrappers
18
+ - Google ADK `FunctionTool` option wrappers
19
+
20
+ ## Install
21
+
22
+ ```sh
23
+ pnpm add @runlayer/hooks-sdk@0.1.0
24
+ ```
25
+
26
+ Install the framework package you use separately, such as
27
+ `@anthropic-ai/claude-agent-sdk`, `ai`, `@openai/agents`, or `@google/adk`.
28
+
29
+ ## Configure
30
+
31
+ ```sh
32
+ export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
33
+ export RUNLAYER_API_KEY="rl_..."
34
+ ```
35
+
36
+ For agent account authentication, set client credentials instead:
37
+
38
+ ```sh
39
+ export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
40
+ export RUNLAYER_AGENT_CLIENT_ID="client_..."
41
+ export RUNLAYER_AGENT_CLIENT_SECRET="..."
42
+ ```
43
+
44
+ The SDK exchanges these credentials for a Runlayer bearer token with
45
+ `client_credentials`, then caches and refreshes that token internally. Do not
46
+ configure or pass a pre-minted bearer token.
47
+
48
+ For OBO agent tokens, also set:
49
+
50
+ ```sh
51
+ export RUNLAYER_AGENT_SUBJECT_TOKEN="user@example.com"
52
+ export RUNLAYER_AGENT_SUBJECT_TOKEN_TYPE="urn:runlayer:token-type:user-email"
53
+ ```
54
+
55
+ `RunlayerClient.fromEnv()` defaults to `client: "typescript-sdk"` so phase 1
56
+ events are attributed to the first-party Hooks TypeScript SDK in Runlayer.
57
+
58
+ Optional runtime controls:
59
+
60
+ | Variable | Purpose |
61
+ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------- |
62
+ | `RUNLAYER_HOOK_TIMEOUT_MS` | Hook request timeout. Defaults to `10000`. |
63
+ | `RUNLAYER_HOOK_MAX_TOOL_OUTPUT_BYTES` | Maximum serialized tool output sent to Runlayer. Defaults to `65536`. |
64
+ | `RUNLAYER_HOOK_ENFORCEMENT_FAILURE_MODE` | Defaults to `closed`; set to `open` only if tool calls should continue when Runlayer is unreachable. |
65
+ | `RUNLAYER_ALLOW_INSECURE_TRANSPORT=1` | Allow non-HTTPS `RUNLAYER_BASE_URL` for local development. |
66
+
67
+ Enforcement calls fail closed by default. Lifecycle telemetry is best-effort
68
+ unless a helper documents strict behavior. Tool output is capped before upload,
69
+ and failed tool details include bounded stdout/stderr/output fields with
70
+ truncation metadata.
71
+
72
+ The SDK skips pre-tool and post-tool enforcement for Runlayer's own MCP server
73
+ names (`runlayer`, `runlayer-plugin`, and `onelayer`) and for MCP calls whose
74
+ `toolUrl` points at a Runlayer proxy URL. Third-party MCP tools stay enforced by
75
+ default. Use `shouldEnforceTool(...)` or `toolEnforcement` when building a
76
+ custom TypeScript adapter. Additional `ignoredMcpServerNames` are added to the
77
+ default Runlayer self-MCP skip list; set `skipRunlayerSelfMcp: false` only if you
78
+ need to enforce those self-MCP names. If you call `shouldEnforceTool(...)`
79
+ directly with absolute self-hosted Runlayer MCP proxy URLs, pass
80
+ `runlayerBaseUrl`; `RunlayerClient` does this automatically.
81
+
82
+ ## Claude Agent SDK Hooks
83
+
84
+ ```ts
85
+ import { query } from "@anthropic-ai/claude-agent-sdk";
86
+ import {
87
+ claudeAgentSdkAssistantMessageToTranscriptLine,
88
+ createClaudeAgentSdkHooks,
89
+ emitClaudeAgentSdkTranscriptStop,
90
+ RunlayerClient,
91
+ } from "@runlayer/hooks-sdk/claude-agent-sdk";
92
+
93
+ const runlayer = RunlayerClient.fromEnv({
94
+ clientVersion: "my-agent/1.0.0",
95
+ });
96
+
97
+ const transcriptLines: string[] = [];
98
+ let sessionId: string | undefined;
99
+
100
+ for await (const message of query({
101
+ prompt: "Inspect this workspace",
102
+ options: {
103
+ hooks: createClaudeAgentSdkHooks(runlayer, { includeStop: false }),
104
+ thinking: { type: "adaptive" },
105
+ },
106
+ })) {
107
+ if (message.type === "system" && message.subtype === "init") {
108
+ sessionId = message.session_id;
109
+ }
110
+
111
+ if (message.type === "assistant") {
112
+ transcriptLines.push(claudeAgentSdkAssistantMessageToTranscriptLine(message.message));
113
+ }
114
+ }
115
+
116
+ if (sessionId) {
117
+ await emitClaudeAgentSdkTranscriptStop(runlayer, {
118
+ model: "claude-agent-sdk",
119
+ sessionId,
120
+ transcriptLines,
121
+ });
122
+ }
123
+ ```
124
+
125
+ Use `includeStop: false` when you emit a transcript-bearing `Stop` manually.
126
+ That lets Runlayer extract assistant thinking/reasoning blocks from the
127
+ transcript instead of receiving a bare lifecycle stop.
128
+
129
+ ## Preflight
130
+
131
+ ```ts
132
+ import { RunlayerClient, sendRunlayerPreflight } from "@runlayer/hooks-sdk";
133
+
134
+ const result = await sendRunlayerPreflight(RunlayerClient.fromEnv(), {
135
+ prompt: "Runlayer ingestion preflight",
136
+ });
137
+
138
+ console.log(result.sessionId);
139
+ ```
140
+
141
+ ## Tool Wrapping
142
+
143
+ Use `runTool` when you are invoking tools yourself rather than through a Claude
144
+ Agent SDK hook.
145
+
146
+ ```ts
147
+ const output = await runlayer.runTool({
148
+ execute: async (toolInput) => {
149
+ return runLocalTool(toolInput);
150
+ },
151
+ sessionId: "session-id",
152
+ toolInput: { command: "cat README.md" },
153
+ toolName: "Bash",
154
+ toolType: "shell",
155
+ });
156
+ ```
157
+
158
+ Pass `toolUrl` when wrapping MCP tools manually. Runlayer proxy URLs such as
159
+ `/api/v1/proxy/<id>/mcp`, `/api/v1/proxy/plugins/<id>/mcp`,
160
+ `/api/v1/proxy/skills/<id>/mcp`, and `/api/v1/proxy/agent-account/<id>/mcp` are
161
+ skipped automatically because the proxy already runs MCP policy and scanner
162
+ enforcement.
163
+
164
+ ## Vercel AI SDK Tools
165
+
166
+ Wrap a Vercel AI SDK tool set before passing it to `generateText`,
167
+ `streamText`, or a `ToolLoopAgent`.
168
+
169
+ ```ts
170
+ import { streamText, tool } from "ai";
171
+ import { withRunlayerVercelAiTools, RunlayerClient } from "@runlayer/hooks-sdk/vercel-ai-sdk";
172
+
173
+ const runlayer = RunlayerClient.fromEnv({
174
+ clientVersion: "my-agent/1.0.0",
175
+ });
176
+
177
+ const tools = withRunlayerVercelAiTools(
178
+ {
179
+ getWeather: tool({
180
+ description: "Get weather for a city",
181
+ inputSchema: {
182
+ type: "object",
183
+ properties: { city: { type: "string" } },
184
+ required: ["city"],
185
+ },
186
+ execute: async ({ city }) => ({ forecast: `sunny in ${city}` }),
187
+ }),
188
+ },
189
+ {
190
+ client: runlayer,
191
+ sessionId: "session-id",
192
+ },
193
+ );
194
+
195
+ await streamText({
196
+ model,
197
+ prompt: "Check the weather in Paris",
198
+ tools,
199
+ });
200
+ ```
201
+
202
+ The adapter preserves the Vercel execution options and forwards `toolCallId` to
203
+ Runlayer as `toolUseId`.
204
+
205
+ ## OpenAI Agents SDK Tools
206
+
207
+ Wrap function tool options before passing them to OpenAI Agents SDK's `tool(...)`
208
+ helper.
209
+
210
+ ```ts
211
+ import { tool } from "@openai/agents";
212
+ import {
213
+ withRunlayerOpenAIAgentsTool,
214
+ RunlayerClient,
215
+ } from "@runlayer/hooks-sdk/openai-agents-sdk";
216
+
217
+ const runlayer = RunlayerClient.fromEnv({
218
+ clientVersion: "my-agent/1.0.0",
219
+ });
220
+
221
+ const lookupTicket = tool(
222
+ withRunlayerOpenAIAgentsTool(
223
+ {
224
+ name: "lookup_ticket",
225
+ description: "Look up a support ticket",
226
+ parameters: {
227
+ type: "object",
228
+ properties: { ticketId: { type: "string" } },
229
+ required: ["ticketId"],
230
+ },
231
+ execute: async ({ ticketId }) => `ticket:${ticketId}`,
232
+ },
233
+ {
234
+ client: runlayer,
235
+ sessionId: "session-id",
236
+ },
237
+ ),
238
+ );
239
+ ```
240
+
241
+ The adapter preserves `context` and `details` arguments and reads common
242
+ `toolCall` IDs from `details`.
243
+
244
+ ## Google ADK Tools
245
+
246
+ Wrap Google ADK `FunctionTool` options before constructing the tool.
247
+
248
+ ```ts
249
+ import { FunctionTool } from "@google/adk";
250
+ import { withRunlayerGoogleAdkTool, RunlayerClient } from "@runlayer/hooks-sdk/google-adk";
251
+
252
+ const runlayer = RunlayerClient.fromEnv({
253
+ clientVersion: "my-agent/1.0.0",
254
+ });
255
+
256
+ const searchTickets = new FunctionTool(
257
+ withRunlayerGoogleAdkTool(
258
+ {
259
+ name: "search_tickets",
260
+ description: "Search support tickets",
261
+ parameters: {
262
+ type: "object",
263
+ properties: { query: { type: "string" } },
264
+ required: ["query"],
265
+ },
266
+ execute: async ({ query }) => ({ query }),
267
+ },
268
+ {
269
+ client: runlayer,
270
+ sessionId: "session-id",
271
+ },
272
+ ),
273
+ );
274
+ ```
275
+
276
+ ## Direct MCP Source Enforcement
277
+
278
+ When the deployment exposes direct MCP source validation, configure the endpoint
279
+ path and call `enforceMcpSource` before executing a direct MCP tool.
280
+
281
+ ```ts
282
+ const runlayer = RunlayerClient.fromEnv({
283
+ directMcpSourceEnforcementPath: "/api/v1/hooks/direct-mcp-source",
284
+ });
285
+
286
+ await runlayer.enforceMcpSource({
287
+ generationId: "generation-id",
288
+ sessionId: "session-id",
289
+ toolName: "mcp__github__list_repos",
290
+ url: "https://tenant.runlayer.com/api/v1/proxy/server-id/mcp",
291
+ });
292
+ ```
@@ -0,0 +1,43 @@
1
+ import { RunlayerClient, type HookEventName, type JsonObject } from "./client.js";
2
+ export type ClaudeAgentSdkHookEvent = HookEventName;
3
+ export type ClaudeAgentSdkHookInput = JsonObject & {
4
+ hook_event_name: string;
5
+ session_id?: string;
6
+ tool_input?: unknown;
7
+ tool_name?: string;
8
+ tool_response?: unknown;
9
+ tool_url?: string;
10
+ tool_use_id?: string;
11
+ };
12
+ export type ClaudeAgentSdkHookJsonOutput = JsonObject & {
13
+ continue?: boolean;
14
+ hookSpecificOutput?: JsonObject;
15
+ reason?: string;
16
+ stopReason?: string;
17
+ systemMessage?: string;
18
+ };
19
+ export type ClaudeAgentSdkHookCallback = (input: ClaudeAgentSdkHookInput, toolUseId?: string, options?: {
20
+ signal?: AbortSignal;
21
+ }) => ClaudeAgentSdkHookJsonOutput | Promise<ClaudeAgentSdkHookJsonOutput>;
22
+ export type ClaudeAgentSdkHookCallbackMatcher = {
23
+ hooks: ClaudeAgentSdkHookCallback[];
24
+ matcher?: string;
25
+ };
26
+ export type ClaudeAgentSdkHooksOptions = {
27
+ includeStop?: boolean;
28
+ };
29
+ export type ClaudeAgentSdkTranscriptStopOptions = {
30
+ extraPayload?: JsonObject;
31
+ model: string;
32
+ sessionId: string;
33
+ source?: string;
34
+ strict?: boolean;
35
+ transcriptLines: readonly string[];
36
+ };
37
+ export declare function createClaudeAgentSdkHooks(client: RunlayerClient, options?: ClaudeAgentSdkHooksOptions): Partial<Record<ClaudeAgentSdkHookEvent, ClaudeAgentSdkHookCallbackMatcher[]>>;
38
+ export declare function claudeAgentSdkAssistantMessageToTranscriptLine(assistantMessage: unknown): string;
39
+ export declare function emitClaudeAgentSdkTranscriptStop(client: RunlayerClient, options: ClaudeAgentSdkTranscriptStopOptions): Promise<void>;
40
+ export declare function toolTypeFromName(toolName: string): string;
41
+ export { RunlayerBlockedError, RunlayerClient, RunlayerHookClient, isRunlayerMcpProxyUrl, mcpServerNameFromToolName, shouldEnforceTool, } from "./client.js";
42
+ export type { JsonObject, RunlayerToolContext, RunlayerToolEnforcementOptions, RunlayerToolEnforcementPredicate, } from "./client.js";
43
+ //# sourceMappingURL=claude-agent-sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-agent-sdk.d.ts","sourceRoot":"","sources":["../src/claude-agent-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAGrB,MAAM,MAAM,uBAAuB,GAAG,aAAa,CAAC;AAEpD,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG,UAAU,GAAG;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,UAAU,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,CACvC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAC/B,4BAA4B,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;AAE1E,MAAM,MAAM,iCAAiC,GAAG;IAC9C,KAAK,EAAE,0BAA0B,EAAE,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG;IAChD,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,CAAC;AAEF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,MAAM,CAAC,uBAAuB,EAAE,iCAAiC,EAAE,CAAC,CAAC,CAe/E;AAED,wBAAgB,8CAA8C,CAAC,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAEhG;AAED,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC,IAAI,CAAC,CAYf;AAwMD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAqBzD;AAED,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,aAAa,CAAC"}
@@ -0,0 +1,202 @@
1
+ import { RunlayerBlockedError, } from "./client.js";
2
+ import { stripUndefined } from "./internal.js";
3
+ export function createClaudeAgentSdkHooks(client, options = {}) {
4
+ const hooks = {
5
+ SessionStart: [{ hooks: [createLifecycleHook(client, "SessionStart")] }],
6
+ SessionEnd: [{ hooks: [createLifecycleHook(client, "SessionEnd")] }],
7
+ UserPromptSubmit: [{ hooks: [createLifecycleHook(client, "UserPromptSubmit")] }],
8
+ PreToolUse: [{ hooks: [createPreToolUseHook(client)] }],
9
+ PostToolUse: [{ hooks: [createPostToolUseHook(client)] }],
10
+ PostToolUseFailure: [{ hooks: [createPostToolUseFailureHook(client)] }],
11
+ };
12
+ if (options.includeStop ?? true) {
13
+ hooks.Stop = [{ hooks: [createLifecycleHook(client, "Stop")] }];
14
+ }
15
+ return hooks;
16
+ }
17
+ export function claudeAgentSdkAssistantMessageToTranscriptLine(assistantMessage) {
18
+ return JSON.stringify({ message: assistantMessage });
19
+ }
20
+ export async function emitClaudeAgentSdkTranscriptStop(client, options) {
21
+ await client.emitEvent("Stop", {
22
+ model: options.model,
23
+ session_id: options.sessionId,
24
+ source: options.source ?? "claude-agent-sdk",
25
+ ...options.extraPayload,
26
+ }, options.transcriptLines.join("\n"), { strict: options.strict ?? true });
27
+ }
28
+ function createLifecycleHook(client, eventName) {
29
+ return async (input, toolUseId) => {
30
+ await client.emitEvent(eventName, {
31
+ ...hookInputPayload(input),
32
+ tool_use_id: toolUseId ?? toolUseIdFromInput(input),
33
+ });
34
+ return {};
35
+ };
36
+ }
37
+ function createPreToolUseHook(client) {
38
+ return async (input, toolUseId) => {
39
+ if (!isPreToolUseInput(input)) {
40
+ return {};
41
+ }
42
+ try {
43
+ const result = await client.beforeTool({
44
+ sessionId: input.session_id,
45
+ toolInput: asJsonObject(input.tool_input),
46
+ toolName: input.tool_name,
47
+ toolType: toolTypeFromName(input.tool_name),
48
+ toolUrl: toolUrlFromInput(input),
49
+ toolUseId: toolUseId ?? input.tool_use_id,
50
+ });
51
+ if (!result.modified) {
52
+ return {};
53
+ }
54
+ return {
55
+ hookSpecificOutput: {
56
+ hookEventName: "PreToolUse",
57
+ permissionDecision: "allow",
58
+ updatedInput: result.toolInput,
59
+ },
60
+ };
61
+ }
62
+ catch (error) {
63
+ if (error instanceof RunlayerBlockedError) {
64
+ return {
65
+ reason: error.message,
66
+ hookSpecificOutput: {
67
+ hookEventName: "PreToolUse",
68
+ permissionDecision: "deny",
69
+ permissionDecisionReason: error.message,
70
+ },
71
+ };
72
+ }
73
+ throw error;
74
+ }
75
+ };
76
+ }
77
+ function createPostToolUseHook(client) {
78
+ return async (input, toolUseId) => {
79
+ if (!isPostToolUseInput(input)) {
80
+ return {};
81
+ }
82
+ try {
83
+ await client.afterTool({
84
+ durationMs: durationMsFromHookInput(input),
85
+ sessionId: input.session_id,
86
+ toolInput: asJsonObject(input.tool_input),
87
+ toolName: input.tool_name,
88
+ toolOutput: input.tool_response,
89
+ toolType: toolTypeFromName(input.tool_name),
90
+ toolUrl: toolUrlFromInput(input),
91
+ toolUseId: toolUseId ?? input.tool_use_id,
92
+ });
93
+ return {};
94
+ }
95
+ catch (error) {
96
+ if (error instanceof RunlayerBlockedError) {
97
+ return blockedPostToolOutput("PostToolUse", error.message);
98
+ }
99
+ throw error;
100
+ }
101
+ };
102
+ }
103
+ function createPostToolUseFailureHook(client) {
104
+ return async (input, toolUseId) => {
105
+ if (!isPostToolUseFailureInput(input)) {
106
+ return {};
107
+ }
108
+ try {
109
+ await client.afterTool({
110
+ durationMs: durationMsFromHookInput(input),
111
+ errorMessage: input.error,
112
+ isError: true,
113
+ sessionId: input.session_id,
114
+ toolInput: asJsonObject(input.tool_input),
115
+ toolName: input.tool_name,
116
+ toolOutput: input.tool_response ?? input.error,
117
+ toolType: toolTypeFromName(input.tool_name),
118
+ toolUrl: toolUrlFromInput(input),
119
+ toolUseId: toolUseId ?? input.tool_use_id,
120
+ });
121
+ return {};
122
+ }
123
+ catch (error) {
124
+ if (error instanceof RunlayerBlockedError) {
125
+ return blockedPostToolOutput("PostToolUseFailure", error.message);
126
+ }
127
+ throw error;
128
+ }
129
+ };
130
+ }
131
+ function blockedPostToolOutput(hookEventName, message) {
132
+ return {
133
+ continue: false,
134
+ stopReason: message,
135
+ systemMessage: message,
136
+ hookSpecificOutput: {
137
+ hookEventName,
138
+ updatedMCPToolOutput: `[Blocked by Runlayer] ${message}`,
139
+ updatedToolOutput: `[Blocked by Runlayer] ${message}`,
140
+ },
141
+ };
142
+ }
143
+ function isPreToolUseInput(input) {
144
+ return hasToolHookShape(input, "PreToolUse");
145
+ }
146
+ function isPostToolUseInput(input) {
147
+ return hasToolHookShape(input, "PostToolUse");
148
+ }
149
+ function isPostToolUseFailureInput(input) {
150
+ return hasToolHookShape(input, "PostToolUseFailure");
151
+ }
152
+ function hasToolHookShape(input, hookEventName) {
153
+ return (input.hook_event_name === hookEventName &&
154
+ typeof input.session_id === "string" &&
155
+ typeof input.tool_name === "string");
156
+ }
157
+ function hookInputPayload(input) {
158
+ const payload = input;
159
+ return stripUndefined(payload);
160
+ }
161
+ function toolUseIdFromInput(input) {
162
+ if ("tool_use_id" in input && typeof input.tool_use_id === "string") {
163
+ return input.tool_use_id;
164
+ }
165
+ return undefined;
166
+ }
167
+ function toolUrlFromInput(input) {
168
+ const candidates = [input.tool_url, input.url, input.mcp_url, input.server_url];
169
+ return candidates.find((candidate) => typeof candidate === "string");
170
+ }
171
+ function asJsonObject(value) {
172
+ if (value && typeof value === "object" && !Array.isArray(value)) {
173
+ return value;
174
+ }
175
+ return { value };
176
+ }
177
+ function durationMsFromHookInput(input) {
178
+ const candidate = input.duration_ms;
179
+ return typeof candidate === "number" ? candidate : undefined;
180
+ }
181
+ export function toolTypeFromName(toolName) {
182
+ if (toolName.startsWith("mcp__")) {
183
+ return "mcp";
184
+ }
185
+ const lower = toolName.toLowerCase();
186
+ if (lower === "bash" || lower === "shell") {
187
+ return "shell";
188
+ }
189
+ if (lower === "read" || lower === "readfile") {
190
+ return "file_read";
191
+ }
192
+ if (lower === "write" ||
193
+ lower === "edit" ||
194
+ lower === "multiedit" ||
195
+ lower === "writefile" ||
196
+ lower === "editfile") {
197
+ return "file_write";
198
+ }
199
+ return "other";
200
+ }
201
+ export { RunlayerBlockedError, RunlayerClient, RunlayerHookClient, isRunlayerMcpProxyUrl, mcpServerNameFromToolName, shouldEnforceTool, } from "./client.js";
202
+ //# sourceMappingURL=claude-agent-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-agent-sdk.js","sourceRoot":"","sources":["../src/claude-agent-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAIrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AA8C/C,MAAM,UAAU,yBAAyB,CACvC,MAAsB,EACtB,UAAsC,EAAE;IAExC,MAAM,KAAK,GAAkF;QAC3F,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACxE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC;QACpE,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC;QAChF,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACvD,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACzD,kBAAkB,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;KACxE,CAAC;IAEF,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,8CAA8C,CAAC,gBAAyB;IACtF,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,MAAsB,EACtB,OAA4C;IAE5C,MAAM,MAAM,CAAC,SAAS,CACpB,MAAM,EACN;QACE,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU,EAAE,OAAO,CAAC,SAAS;QAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,kBAAkB;QAC5C,GAAG,OAAO,CAAC,YAAY;KACxB,EACD,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAClC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CACnC,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,MAAsB,EACtB,SAAwB;IAExB,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAyC,EAAE;QACvE,MAAM,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE;YAChC,GAAG,gBAAgB,CAAC,KAAK,CAAC;YAC1B,WAAW,EAAE,SAAS,IAAI,kBAAkB,CAAC,KAAK,CAAC;SACpD,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,MAAsB;IAClD,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAyC,EAAE;QACvE,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC;gBACrC,SAAS,EAAE,KAAK,CAAC,UAAU;gBAC3B,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC;gBACzC,QAAQ,EAAE,KAAK,CAAC,SAAS;gBACzB,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC;gBAC3C,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC;gBAChC,SAAS,EAAE,SAAS,IAAI,KAAK,CAAC,WAAW;aAC1C,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACrB,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,OAAO;gBACL,kBAAkB,EAAE;oBAClB,aAAa,EAAE,YAAY;oBAC3B,kBAAkB,EAAE,OAAO;oBAC3B,YAAY,EAAE,MAAM,CAAC,SAAS;iBAC/B;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;gBAC1C,OAAO;oBACL,MAAM,EAAE,KAAK,CAAC,OAAO;oBACrB,kBAAkB,EAAE;wBAClB,aAAa,EAAE,YAAY;wBAC3B,kBAAkB,EAAE,MAAM;wBAC1B,wBAAwB,EAAE,KAAK,CAAC,OAAO;qBACxC;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAsB;IACnD,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAyC,EAAE;QACvE,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,CAAC;gBACrB,UAAU,EAAE,uBAAuB,CAAC,KAAK,CAAC;gBAC1C,SAAS,EAAE,KAAK,CAAC,UAAU;gBAC3B,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC;gBACzC,QAAQ,EAAE,KAAK,CAAC,SAAS;gBACzB,UAAU,EAAE,KAAK,CAAC,aAAa;gBAC/B,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC;gBAC3C,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC;gBAChC,SAAS,EAAE,SAAS,IAAI,KAAK,CAAC,WAAW;aAC1C,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;gBAC1C,OAAO,qBAAqB,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,MAAsB;IAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAyC,EAAE;QACvE,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,CAAC;gBACrB,UAAU,EAAE,uBAAuB,CAAC,KAAK,CAAC;gBAC1C,YAAY,EAAE,KAAK,CAAC,KAAK;gBACzB,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,KAAK,CAAC,UAAU;gBAC3B,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC;gBACzC,QAAQ,EAAE,KAAK,CAAC,SAAS;gBACzB,UAAU,EAAE,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,KAAK;gBAC9C,QAAQ,EAAE,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC;gBAC3C,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC;gBAChC,SAAS,EAAE,SAAS,IAAI,KAAK,CAAC,WAAW;aAC1C,CAAC,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;gBAC1C,OAAO,qBAAqB,CAAC,oBAAoB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YACpE,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAC5B,aAAmD,EACnD,OAAe;IAEf,OAAO;QACL,QAAQ,EAAE,KAAK;QACf,UAAU,EAAE,OAAO;QACnB,aAAa,EAAE,OAAO;QACtB,kBAAkB,EAAE;YAClB,aAAa;YACb,oBAAoB,EAAE,yBAAyB,OAAO,EAAE;YACxD,iBAAiB,EAAE,yBAAyB,OAAO,EAAE;SACtD;KACF,CAAC;AACJ,CAAC;AAqBD,SAAS,iBAAiB,CAAC,KAA8B;IACvD,OAAO,gBAAgB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,kBAAkB,CAAC,KAA8B;IACxD,OAAO,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,yBAAyB,CAChC,KAA8B;IAE9B,OAAO,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,gBAAgB,CAAC,KAA8B,EAAE,aAAqB;IAC7E,OAAO,CACL,KAAK,CAAC,eAAe,KAAK,aAAa;QACvC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CACpC,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAA8B;IACtD,MAAM,OAAO,GAAG,KAA8B,CAAC;IAC/C,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,kBAAkB,CAAC,KAA8B;IACxD,IAAI,aAAa,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpE,OAAO,KAAK,CAAC,WAAW,CAAC;IAC3B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAA8B;IACtD,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAChF,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAuB,EAAE,CAAC,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,KAAmB,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,SAAS,uBAAuB,CAAC,KAA8B;IAC7D,MAAM,SAAS,GAAI,KAAmC,CAAC,WAAW,CAAC;IACnE,OAAO,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QAC1C,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QAC7C,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IACE,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,WAAW;QACrB,KAAK,KAAK,UAAU,EACpB,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}