@adtl/gateway 0.3.0 → 0.3.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/README.md CHANGED
@@ -138,6 +138,46 @@ adtl-gateway --config adtl.yaml --audit
138
138
 
139
139
  or set `gateway.mode: audit` in the file. In audit mode every call goes through and results are not changed. Labels are still tracked, so the decisions are the same as in active mode. Each line in the audit log gets `"mode": "audit"`, and a call the policy would have stopped is logged as `"outcome": "forwarded"` with `"decision": "ask"` or `"block"`, the reason and the matching rules. Once the log looks right, remove the flag.
140
140
 
141
+ ## Claude Code: cover the built-in tools too
142
+
143
+ The gateway only sees MCP calls. Claude Code's own tools (`WebFetch`, `WebSearch`, `Bash`, `Read`, ...) don't go through it, so a page fetched with `WebFetch` would not taint the session, and `Bash` could send data anywhere. `adtl-gateway hook` closes that gap. Add it to `.claude/settings.json` (or `~/.claude/settings.json` for every project):
144
+
145
+ ```json
146
+ {
147
+ "hooks": {
148
+ "PreToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "npx -y @adtl/gateway hook --config /absolute/path/to/adtl.yaml", "timeout": 10, "onFailure": "block" }] }],
149
+ "PostToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "npx -y @adtl/gateway hook --config /absolute/path/to/adtl.yaml", "timeout": 10 }] }],
150
+ "PostToolUseFailure": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "npx -y @adtl/gateway hook --config /absolute/path/to/adtl.yaml", "timeout": 10 }] }]
151
+ }
152
+ }
153
+ ```
154
+
155
+ (A global install, `npm i -g @adtl/gateway` and then `adtl-gateway hook ...`, starts faster than `npx`.)
156
+
157
+ What it does:
158
+
159
+ - **After each tool runs**, it labels the output and adds it to the session label. Built-in tools are labeled as the server `claude-code`.
160
+ - **Before each tool runs**, it checks the call against the same policy as the gateway. `block` denies the call. `ask` shows Claude Code's own permission prompt, so you approve in the terminal. `allow` gives no answer, so your normal Claude Code permissions still apply. ADTL never approves a call on its own.
161
+ - **It shares one session label with the gateway.** Claude Code gives the gateway its session id (`CLAUDE_CODE_SESSION_ID`), and both keep the label in `~/.adtl/sessions/<id>.jsonl` (set `ADTL_SESSIONS_DIR` to change the directory). A `WebFetch` taints the session for `github__add_comment`, and a private file read through the gateway counts against a later `Bash` call. Labels last for the whole Claude Code session, including `--resume`.
162
+ - **It covers MCP servers that skip the gateway**, such as connectors added in claude.ai. Their tools are labeled as their server name (`mcp__<server>__<tool>` → server `<server>`), so you can describe them under `servers:` like any upstream. The gateway's own tools (`mcp__adtl__*`) are skipped; pass `--gateway-server <name>` if you registered the gateway under another name.
163
+ - **It fails closed.** If the hook can't decide, it exits with code 2, which stops the call.
164
+ - **It writes to the same audit log** (`gateway.audit`) with `"via": "claude-code-hook"`, and follows `gateway.mode: audit`. The config needs no `gateway:` section if you only use the hooks.
165
+
166
+ Built-in labels, which you can override under `servers.claude-code.tools`:
167
+
168
+ | Tools | Result | Egress |
169
+ |---|---|---|
170
+ | `Read`, `Grep`, `Glob` | trusted, private | none |
171
+ | `WebFetch`, `WebSearch` | untrusted, public | external (a URL or query can carry data out) |
172
+ | `Bash`, `Monitor` | unknown, private | unknown |
173
+ | `Agent` / `Task` | unknown, private | none (the sub-agent's own calls are checked too) |
174
+ | `Write`, `Edit`, `TodoWrite`, other bookkeeping tools | trusted, public | none |
175
+ | anything else | your `defaults` | unknown |
176
+
177
+ With the [example policy](../../examples/adtl.yaml), `Bash` and `WebFetch` run freely in a fresh session, but ask first once the session has read untrusted content, because `no-public-write-after-untrusted` matches `tool.egress: [public, external, unknown]`.
178
+
179
+ The hook also refuses `Write` and `Edit` on your ADTL config and session files, and asks before shell commands that mention the session directory, so the agent can't simply clear its own taint. This is a speed bump, not a sandbox.
180
+
141
181
  ## How it works
142
182
 
143
183
  ```
@@ -155,7 +195,8 @@ The gateway fails closed. If an interceptor errors or times out, the call is sto
155
195
  - Tools, resources and prompts are proxied. Resource subscriptions, `list_changed` notifications and completions are not passed through yet.
156
196
  - Resources and prompts are labeled by server defaults (`servers.<id>.defaults`) or the global defaults; there are no per-resource or per-prompt rules yet. A resource URI that two upstreams could serve is refused rather than guessed.
157
197
  - Approvals come from one push channel (ntfy). Other channels, approvals inside the MCP client, and approver roles are planned.
158
- - Labels last for one gateway process, which is one agent session. They are not carried into files, memory or other agents yet; that's planned for v0.4.
198
+ - Labels last for one agent session: one gateway process, or under Claude Code one Claude Code session (shared with the hooks). They are not carried into files, memory or other agents yet; that's planned for v0.4. A file written after reading untrusted content reads back as trusted.
199
+ - The Claude Code hooks label tools by name, not by what they touched: a `Read` of a downloaded file is as trusted as a `Read` of your own code.
159
200
  - Labels are set by your config. Servers' own trust claims can only make labels stricter, unless you set `acceptServerClaims: true`.
160
201
 
161
202
  ## Links
package/dist/audit.d.ts CHANGED
@@ -7,8 +7,10 @@ export interface AuditEntry {
7
7
  tool?: string;
8
8
  resource?: string;
9
9
  prompt?: string;
10
- /** Final outcome of the call. */
11
- outcome: "forwarded" | "blocked" | "upstream_error";
10
+ /** Final outcome of the call. "asked": handed to Claude Code's permission prompt by the hook. */
11
+ outcome: "forwarded" | "blocked" | "asked" | "upstream_error";
12
+ /** Present when the entry was written by the Claude Code hook rather than the gateway. */
13
+ via?: "claude-code-hook";
12
14
  /** The policy's decision. In audit mode a call can be forwarded with decision "ask" or "block". */
13
15
  decision?: string;
14
16
  /** Present when the gateway ran in audit mode: nothing was stopped or changed. */
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,gBAAgB,CAAC;IACpD,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAChC;AAED,qBAAa,aAAc,YAAW,SAAS;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAIjC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAG/B;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,CAAM;IACpC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,YAAY,GAAG,gBAAgB,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,gBAAgB,CAAC;IAC9D,0FAA0F;IAC1F,GAAG,CAAC,EAAE,kBAAkB,CAAC;IACzB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAChC;AAED,qBAAa,aAAc,YAAW,SAAS;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAIjC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAG/B;AAED,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,CAAM;IACpC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAG/B"}
package/dist/audit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC,MAAM,OAAO,aAAa;IACH;IAArB,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;QAC/B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,KAAiB;QACrB,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;CACF;AAED,MAAM,OAAO,cAAc;IAChB,OAAO,GAAiB,EAAE,CAAC;IACpC,KAAK,CAAC,KAAiB;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCpC,MAAM,OAAO,aAAa;IACH;IAArB,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;QAC/B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,KAAiB;QACrB,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;CACF;AAED,MAAM,OAAO,cAAc;IAChB,OAAO,GAAiB,EAAE,CAAC;IACpC,KAAK,CAAC,KAAiB;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF"}
package/dist/cli.js CHANGED
@@ -5,6 +5,7 @@
5
5
  *
6
6
  * adtl-gateway --config adtl.yaml [--audit]
7
7
  * adtl-gateway init --config adtl.yaml [--write]
8
+ * adtl-gateway hook --config adtl.yaml [--gateway-server adtl]
8
9
  *
9
10
  * Point your MCP client (e.g. Claude Code's .mcp.json) at this command.
10
11
  * Logs go to stderr; stdout carries MCP JSON-RPC only.
@@ -12,10 +13,12 @@
12
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
14
  import { EnvExpansionError } from "./config.js";
14
15
  import { GATEWAY_VERSION } from "./gateway.js";
16
+ import { runHook } from "./hooks/run.js";
15
17
  import { runInit } from "./init/run.js";
16
18
  import { GatewayConfigError, loadGatewayConfig, startGateway } from "./startup.js";
17
19
  const USAGE = `Usage: adtl-gateway --config <adtl.yaml> [--audit]
18
20
  adtl-gateway init --config <adtl.yaml> [--write]
21
+ adtl-gateway hook --config <adtl.yaml> [--gateway-server <name>]
19
22
 
20
23
  Runs an MCP server over stdio that forwards tool calls to the upstream
21
24
  servers in the config, checking and labeling each call with ADTL.
@@ -32,6 +35,17 @@ init:
32
35
  filesystem and fetch; MCP tool hints otherwise). Existing entries are
33
36
  never changed. Prints the updated config; review it before using it.
34
37
  --write Update the config file in place (original kept as .bak).
38
+
39
+ hook:
40
+ The Claude Code hook for PreToolUse, PostToolUse and PostToolUseFailure.
41
+ Labels built-in tools (WebFetch, Read, Bash, ...) and MCP servers outside
42
+ the gateway, and runs the same policy on them, sharing the session label
43
+ with the gateway. Reads the hook event from stdin.
44
+ --gateway-server <name>
45
+ The gateway's name in Claude Code's MCP config; its
46
+ tools are checked by the gateway and skipped here.
47
+ Default: adtl.
48
+
35
49
  -h, --help Show this help.`;
36
50
  function parseArgs(argv) {
37
51
  const out = {};
@@ -39,6 +53,10 @@ function parseArgs(argv) {
39
53
  const a = argv[i];
40
54
  if (i === 0 && a === "init")
41
55
  out.init = true;
56
+ else if (i === 0 && a === "hook")
57
+ out.hook = true;
58
+ else if (a === "--gateway-server" && out.hook)
59
+ out.gatewayServer = argv[++i];
42
60
  else if (a === "-h" || a === "--help")
43
61
  out.help = true;
44
62
  else if (a === "-v" || a === "--version")
@@ -67,6 +85,8 @@ async function main() {
67
85
  throw new GatewayConfigError(`Missing --config\n\n${USAGE}`);
68
86
  if (args.init)
69
87
  return init(args.config, args.write === true);
88
+ if (args.hook)
89
+ return hook(args.config, args.gatewayServer);
70
90
  const loaded = await loadGatewayConfig(args.config);
71
91
  if (args.audit)
72
92
  loaded.gateway.mode = "audit";
@@ -111,6 +131,20 @@ function summarize(r, path, write) {
111
131
  : "Nothing written. Review the config above, then re-run with --write.";
112
132
  return `${lines.join("\n")}\n${tail}`;
113
133
  }
134
+ async function readStdin() {
135
+ const chunks = [];
136
+ for await (const c of process.stdin)
137
+ chunks.push(c);
138
+ return Buffer.concat(chunks).toString("utf8");
139
+ }
140
+ async function hook(config, gatewayServer) {
141
+ const out = await runHook({ configPath: config, stdin: await readStdin(), ...(gatewayServer ? { gatewayServer } : {}) });
142
+ if (out.stdout)
143
+ process.stdout.write(`${JSON.stringify(out.stdout)}\n`);
144
+ if (out.stderr)
145
+ process.stderr.write(`${out.stderr}\n`);
146
+ process.exitCode = out.exitCode;
147
+ }
114
148
  async function init(path, write) {
115
149
  const result = await runInit({ path, write });
116
150
  if (!write)
@@ -122,6 +156,7 @@ async function init(path, write) {
122
156
  main().catch((err) => {
123
157
  const known = err instanceof GatewayConfigError || err instanceof EnvExpansionError;
124
158
  console.error(known ? `[adtl-gateway] ${err.message}` : err);
125
- process.exit(1);
159
+ // For Claude Code hooks only exit code 2 stops the call; any other code lets it run.
160
+ process.exit(process.argv[2] === "hook" ? 2 : 1);
126
161
  });
127
162
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/gateway.d.ts CHANGED
@@ -4,7 +4,7 @@ import { type CallToolResult, type GetPromptResult, type Prompt, type ReadResour
4
4
  import type { ApprovalBroker } from "./approvals.js";
5
5
  import type { AuditSink } from "./audit.js";
6
6
  import type { InterceptorInvoker } from "./invoker.js";
7
- export declare const GATEWAY_VERSION = "0.3.0";
7
+ export declare const GATEWAY_VERSION = "0.3.1";
8
8
  /** `_meta` key on gateway-generated error results describing why a call was stopped. */
9
9
  export declare const GATEWAY_DECISION_KEY = "adtl/gateway";
10
10
  export interface GatewayLogger {
package/dist/gateway.js CHANGED
@@ -27,7 +27,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
27
27
  import { UriTemplate } from "@modelcontextprotocol/sdk/shared/uriTemplate.js";
28
28
  import { CallToolRequestSchema, ErrorCode, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, McpError, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
29
29
  import { TOOL_SEPARATOR } from "./config.js";
30
- export const GATEWAY_VERSION = "0.3.0";
30
+ export const GATEWAY_VERSION = "0.3.1";
31
31
  /** `_meta` key on gateway-generated error results describing why a call was stopped. */
32
32
  export const GATEWAY_DECISION_KEY = "adtl/gateway";
33
33
  const stderrLogger = {
@@ -0,0 +1,43 @@
1
+ import { type AdtlConfig, type SessionStore } from "@adtl/labels";
2
+ import type { AuditSink } from "../audit.js";
3
+ export interface HookInput {
4
+ session_id?: string;
5
+ hook_event_name?: string;
6
+ tool_name?: string;
7
+ tool_input?: unknown;
8
+ tool_response?: unknown;
9
+ /** PostToolUseFailure: the error the tool returned. */
10
+ error?: unknown;
11
+ cwd?: string;
12
+ }
13
+ export interface HookOptions {
14
+ config: AdtlConfig;
15
+ sessions: SessionStore;
16
+ /** Name of the gateway in Claude Code's MCP config; its tools are skipped. Default `adtl`. */
17
+ gatewayServer?: string;
18
+ /** `audit`: decide and log, but never deny or ask. */
19
+ mode?: "active" | "audit";
20
+ audit?: AuditSink;
21
+ /** Files the agent must not change: the ADTL config and the session directory. */
22
+ protect?: {
23
+ configPath?: string;
24
+ sessionsDir?: string;
25
+ };
26
+ }
27
+ /** What the hook process prints and exits with. */
28
+ export interface HookOutcome {
29
+ stdout?: Record<string, unknown>;
30
+ stderr?: string;
31
+ exitCode: number;
32
+ }
33
+ /** `config` with labels for Claude Code's built-in tools; rules under `servers.claude-code` win. */
34
+ export declare function withClaudeCodePreset(config: AdtlConfig): AdtlConfig;
35
+ /** Which ADTL server and tool a Claude Code tool name is, or undefined for the gateway's own tools. */
36
+ export declare function routeTool(toolName: string, gatewayServer?: string): {
37
+ server: string;
38
+ tool: string;
39
+ } | undefined;
40
+ export declare function handleHook(input: HookInput, opts: HookOptions): HookOutcome;
41
+ /** Fail closed: exit 2 stops a PreToolUse call and shows the reason to Claude. */
42
+ export declare function failure(event: string | undefined, why: string): HookOutcome;
43
+ //# sourceMappingURL=claudeCode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeCode.d.ts","sourceRoot":"","sources":["../../src/hooks/claudeCode.ts"],"names":[],"mappings":"AAsBA,OAAO,EAKL,KAAK,UAAU,EAGf,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,aAAa,CAAC;AAGzD,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uDAAuD;IACvD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,8FAA8F;IAC9F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,kFAAkF;IAClF,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAanE;AAED,uGAAuG;AACvG,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,SAAS,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAKhH;AAuCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,GAAG,WAAW,CA2D3E;AAED,kFAAkF;AAClF,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAG3E"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Claude Code hooks adapter: puts Claude Code's built-in tools (WebFetch, Read,
3
+ * Bash, …) and MCP servers that don't go through the gateway under the same
4
+ * labels and policy as gateway calls.
5
+ *
6
+ * PreToolUse runs the policy against the session label:
7
+ * block → deny, ask → Claude Code's permission prompt,
8
+ * allow → no answer, so Claude Code's own permissions apply
9
+ * PostToolUse labels the tool's output and adds it to the session label
10
+ * PostToolUseFailure same: a failed tool's error output still reaches the model
11
+ *
12
+ * Built-in tools are labeled as the server `claude-code` (see preset.ts); MCP
13
+ * tools `mcp__<server>__<tool>` as `<server>`. Tools of the gateway's own MCP
14
+ * server (`mcp__adtl__*` by default) are skipped: the gateway checks those.
15
+ *
16
+ * Hooks and gateway share one session label through a FileSessionStore keyed
17
+ * by Claude Code's session id, which the gateway reads from
18
+ * `CLAUDE_CODE_SESSION_ID`.
19
+ *
20
+ * Errors fail closed: a PreToolUse hook that can't decide denies the call.
21
+ */
22
+ import { isAbsolute, relative, resolve, sep } from "node:path";
23
+ import { callHash, evaluatePolicy, labelResult, toolEgress, } from "@adtl/labels";
24
+ import { CLAUDE_CODE_PRESET, CLAUDE_CODE_SERVER } from "./preset.js";
25
+ const NOTHING = { exitCode: 0 };
26
+ /** `config` with labels for Claude Code's built-in tools; rules under `servers.claude-code` win. */
27
+ export function withClaudeCodePreset(config) {
28
+ const own = config.servers[CLAUDE_CODE_SERVER];
29
+ return {
30
+ ...config,
31
+ servers: {
32
+ ...config.servers,
33
+ [CLAUDE_CODE_SERVER]: {
34
+ acceptServerClaims: own?.acceptServerClaims ?? false,
35
+ ...(own?.defaults ? { defaults: own.defaults } : {}),
36
+ tools: { ...CLAUDE_CODE_PRESET, ...own?.tools },
37
+ },
38
+ },
39
+ };
40
+ }
41
+ /** Which ADTL server and tool a Claude Code tool name is, or undefined for the gateway's own tools. */
42
+ export function routeTool(toolName, gatewayServer = "adtl") {
43
+ const m = /^mcp__(.+?)__(.+)$/.exec(toolName);
44
+ if (!m)
45
+ return { server: CLAUDE_CODE_SERVER, tool: toolName };
46
+ if (m[1] === gatewayServer)
47
+ return undefined;
48
+ return { server: m[1], tool: m[2] };
49
+ }
50
+ function isRecord(v) {
51
+ return typeof v === "object" && v !== null && !Array.isArray(v);
52
+ }
53
+ function inside(path, dir) {
54
+ const r = relative(dir, path);
55
+ return r === "" || (!r.startsWith(`..${sep}`) && r !== ".." && !isAbsolute(r));
56
+ }
57
+ /**
58
+ * A best-effort guard against the agent clearing its own taint by editing the
59
+ * config or deleting session files. Not a sandbox: Bash can always find a way.
60
+ */
61
+ function protectedTarget(input, route, protect) {
62
+ if (!protect || route.server !== CLAUDE_CODE_SERVER)
63
+ return undefined;
64
+ const args = isRecord(input.tool_input) ? input.tool_input : {};
65
+ const cwd = input.cwd ?? process.cwd();
66
+ const path = typeof args.file_path === "string" ? args.file_path : typeof args.notebook_path === "string" ? args.notebook_path : undefined;
67
+ if (path !== undefined && ["Write", "Edit", "MultiEdit", "NotebookEdit"].includes(route.tool)) {
68
+ const abs = resolve(cwd, path);
69
+ if (protect.configPath && abs === resolve(protect.configPath)) {
70
+ return { decision: "block", reason: "The agent may not change the ADTL config; edit it yourself" };
71
+ }
72
+ if (protect.sessionsDir && inside(abs, resolve(protect.sessionsDir))) {
73
+ return { decision: "block", reason: "The agent may not change ADTL session labels" };
74
+ }
75
+ }
76
+ const command = typeof args.command === "string" ? args.command : undefined;
77
+ if (command !== undefined && ["Bash", "Monitor"].includes(route.tool)) {
78
+ const marks = [".adtl/sessions", protect.sessionsDir].filter((m) => !!m);
79
+ if (marks.some((m) => command.includes(m))) {
80
+ return { decision: "ask", reason: "This command touches ADTL session labels" };
81
+ }
82
+ }
83
+ return undefined;
84
+ }
85
+ export function handleHook(input, opts) {
86
+ const event = input.hook_event_name;
87
+ if (event !== "PreToolUse" && event !== "PostToolUse" && event !== "PostToolUseFailure")
88
+ return NOTHING;
89
+ if (typeof input.tool_name !== "string" || typeof input.session_id !== "string" || input.session_id === "") {
90
+ return failure(event, "hook input has no tool_name or session_id");
91
+ }
92
+ const route = routeTool(input.tool_name, opts.gatewayServer);
93
+ if (!route)
94
+ return NOTHING;
95
+ const config = withClaudeCodePreset(opts.config);
96
+ const ts = new Date().toISOString();
97
+ const base = { ts, sessionId: input.session_id, event: "tools/call", ...route, via: "claude-code-hook" };
98
+ if (event !== "PreToolUse") {
99
+ const label = labelResult({ ...route, result: input.tool_response ?? input.error ?? null }, config);
100
+ const sessionLabel = opts.sessions.observe(input.session_id, label);
101
+ opts.audit?.write({ ...base, outcome: "forwarded", label, sessionLabel, durationMs: 0 });
102
+ return NOTHING;
103
+ }
104
+ const hash = callHash(route.server, route.tool, input.tool_input ?? {});
105
+ const session = opts.sessions.get(input.session_id);
106
+ const guard = protectedTarget(input, route, opts.protect);
107
+ const policy = evaluatePolicy(config.policy, {
108
+ session,
109
+ ...route,
110
+ egress: toolEgress(config, route.server, route.tool),
111
+ });
112
+ const d = guard && (guard.decision === "block" || policy.decision === "allow")
113
+ ? { decision: guard.decision, reason: guard.reason, matched: ["adtl-self-protection"] }
114
+ : policy;
115
+ if (d.decision === "allow")
116
+ return NOTHING;
117
+ const audit = opts.mode === "audit";
118
+ const entry = {
119
+ ...base,
120
+ outcome: audit ? "forwarded" : d.decision === "ask" ? "asked" : "blocked",
121
+ decision: d.decision,
122
+ ...(audit ? { mode: "audit" } : {}),
123
+ reason: d.reason,
124
+ matched: d.matched,
125
+ callHash: hash,
126
+ sessionLabel: session,
127
+ durationMs: 0,
128
+ };
129
+ opts.audit?.write(entry);
130
+ if (audit)
131
+ return NOTHING;
132
+ return {
133
+ exitCode: 0,
134
+ stdout: {
135
+ hookSpecificOutput: {
136
+ hookEventName: "PreToolUse",
137
+ permissionDecision: d.decision === "ask" ? "ask" : "deny",
138
+ permissionDecisionReason: d.decision === "ask" ? `ADTL: ${d.reason}. Approve only if you expected this call.` : `ADTL blocked this call: ${d.reason}.`,
139
+ },
140
+ },
141
+ };
142
+ }
143
+ /** Fail closed: exit 2 stops a PreToolUse call and shows the reason to Claude. */
144
+ export function failure(event, why) {
145
+ const stopped = event === "PreToolUse" ? " The call was stopped." : "";
146
+ return { exitCode: 2, stderr: `ADTL hook error: ${why}.${stopped}` };
147
+ }
148
+ //# sourceMappingURL=claudeCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeCode.js","sourceRoot":"","sources":["../../src/hooks/claudeCode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from "./claudeCode.js";
2
+ export * from "./preset.js";
3
+ export * from "./run.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./claudeCode.js";
2
+ export * from "./preset.js";
3
+ export * from "./run.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Labels for Claude Code's built-in tools, used when `servers.claude-code`
3
+ * doesn't override them. Built-in tools are labeled as the server `claude-code`.
4
+ *
5
+ * - Local reads (Read, Grep, Glob) are trusted but private: your own files.
6
+ * Files written from untrusted content aren't tracked until the v0.4 ledger.
7
+ * - Web tools bring in untrusted content, and their URL or query can carry
8
+ * data out, so their egress is external.
9
+ * - Bash can do anything: its output has unknown integrity, and its egress is
10
+ * unknown.
11
+ * - Edits and bookkeeping tools return nothing worth labeling.
12
+ */
13
+ import type { ToolRule } from "@adtl/labels";
14
+ export declare const CLAUDE_CODE_SERVER = "claude-code";
15
+ export declare const CLAUDE_CODE_PRESET: Record<string, ToolRule>;
16
+ //# sourceMappingURL=preset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/hooks/preset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAOhD,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAyBvD,CAAC"}
@@ -0,0 +1,32 @@
1
+ export const CLAUDE_CODE_SERVER = "claude-code";
2
+ const localRead = { integrity: "trusted", confidentiality: "private", egress: "none" };
3
+ const localWrite = { integrity: "trusted", confidentiality: "public", egress: "none" };
4
+ const web = { integrity: "untrusted", confidentiality: "public", egress: "external" };
5
+ const shell = { integrity: "unknown", confidentiality: "private", egress: "unknown" };
6
+ export const CLAUDE_CODE_PRESET = {
7
+ Read: localRead,
8
+ Grep: localRead,
9
+ Glob: localRead,
10
+ LS: localRead,
11
+ NotebookRead: localRead,
12
+ Write: localWrite,
13
+ Edit: localWrite,
14
+ MultiEdit: localWrite,
15
+ NotebookEdit: localWrite,
16
+ TodoWrite: localWrite,
17
+ AskUserQuestion: localWrite,
18
+ Skill: localWrite,
19
+ ToolSearch: localWrite,
20
+ EnterPlanMode: localWrite,
21
+ ExitPlanMode: localWrite,
22
+ WebFetch: web,
23
+ WebSearch: web,
24
+ Bash: shell,
25
+ BashOutput: shell,
26
+ KillShell: localWrite,
27
+ Monitor: shell,
28
+ // A sub-agent's own tool calls go through these hooks too; its answer mixes what it saw.
29
+ Agent: { integrity: "unknown", confidentiality: "private", egress: "none" },
30
+ Task: { integrity: "unknown", confidentiality: "private", egress: "none" },
31
+ };
32
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../../src/hooks/preset.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAEhD,MAAM,SAAS,GAAa,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACjG,MAAM,UAAU,GAAa,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACjG,MAAM,GAAG,GAAa,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChG,MAAM,KAAK,GAAa,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAEhG,MAAM,CAAC,MAAM,kBAAkB,GAA6B;IAC1D,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,SAAS;IACb,YAAY,EAAE,SAAS;IACvB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,UAAU;IACrB,YAAY,EAAE,UAAU;IACxB,SAAS,EAAE,UAAU;IACrB,eAAe,EAAE,UAAU;IAC3B,KAAK,EAAE,UAAU;IACjB,UAAU,EAAE,UAAU;IACtB,aAAa,EAAE,UAAU;IACzB,YAAY,EAAE,UAAU;IACxB,QAAQ,EAAE,GAAG;IACb,SAAS,EAAE,GAAG;IACd,IAAI,EAAE,KAAK;IACX,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,UAAU;IACrB,OAAO,EAAE,KAAK;IACd,yFAAyF;IACzF,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE;IAC3E,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE;CAC3E,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type HookOutcome } from "./claudeCode.js";
2
+ export interface RunHookOptions {
3
+ configPath: string;
4
+ stdin: string;
5
+ gatewayServer?: string;
6
+ env?: NodeJS.ProcessEnv;
7
+ }
8
+ export declare function runHook(opts: RunHookOptions): Promise<HookOutcome>;
9
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/hooks/run.ts"],"names":[],"mappings":"AAcA,OAAO,EAAuC,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAExF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAyBxE"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `adtl-gateway hook --config adtl.yaml`: the command Claude Code runs for
3
+ * PreToolUse, PostToolUse and PostToolUseFailure. Reads the hook event from
4
+ * stdin and answers on stdout (JSON) or stderr (with exit code 2).
5
+ *
6
+ * The config needs no `gateway:` section; if there is one, its `audit` log and
7
+ * `mode` are used, so hook and gateway write to the same audit log.
8
+ */
9
+ import { readFile } from "node:fs/promises";
10
+ import { dirname, resolve } from "node:path";
11
+ import { FileSessionStore, defaultSessionsDir } from "@adtl/labels";
12
+ import { parseConfigText } from "@adtl/interceptors";
13
+ import { parse as parseYaml } from "yaml";
14
+ import { JsonlAuditLog } from "../audit.js";
15
+ import { failure, handleHook } from "./claudeCode.js";
16
+ export async function runHook(opts) {
17
+ let input;
18
+ try {
19
+ input = JSON.parse(opts.stdin);
20
+ }
21
+ catch {
22
+ // Without the event name we can't tell whether this is a PreToolUse call; refuse it to be safe.
23
+ return failure("PreToolUse", "hook input on stdin is not JSON");
24
+ }
25
+ try {
26
+ const path = resolve(input.cwd ?? process.cwd(), opts.configPath);
27
+ const text = await readFile(path, "utf8");
28
+ const config = parseConfigText(text, path);
29
+ const gw = (parseYaml(text) ?? {}).gateway ?? {};
30
+ const sessionsDir = defaultSessionsDir(opts.env ?? process.env);
31
+ return handleHook(input, {
32
+ config,
33
+ sessions: new FileSessionStore(sessionsDir),
34
+ ...(opts.gatewayServer ? { gatewayServer: opts.gatewayServer } : {}),
35
+ mode: gw.mode === "audit" ? "audit" : "active",
36
+ ...(typeof gw.audit === "string" ? { audit: new JsonlAuditLog(resolve(dirname(path), gw.audit)) } : {}),
37
+ protect: { configPath: path, sessionsDir },
38
+ });
39
+ }
40
+ catch (err) {
41
+ return failure(input.hook_event_name, err.message);
42
+ }
43
+ }
44
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/hooks/run.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAC;AASxF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAoB;IAChD,IAAI,KAAgB,CAAC;IACrB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAc,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,gGAAgG;QAChG,OAAO,OAAO,CAAC,YAAY,EAAE,iCAAiC,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC3C,MAAM,EAAE,GAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAuD,CAAC,OAAO,IAAI,EAAE,CAAC;QACxG,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,UAAU,CAAC,KAAK,EAAE;YACvB,MAAM;YACN,QAAQ,EAAE,IAAI,gBAAgB,CAAC,WAAW,CAAC;YAC3C,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;YAC9C,GAAG,CAAC,OAAO,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvG,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE;SAC3C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,OAAO,CAAC,KAAK,CAAC,eAAe,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -7,4 +7,5 @@ export * from "./email.js";
7
7
  export * from "./gateway.js";
8
8
  export * from "./startup.js";
9
9
  export * from "./init/index.js";
10
+ export * from "./hooks/index.js";
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -7,4 +7,5 @@ export * from "./email.js";
7
7
  export * from "./gateway.js";
8
8
  export * from "./startup.js";
9
9
  export * from "./init/index.js";
10
+ export * from "./hooks/index.js";
10
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}