@arcjet/skills 1.12.0 → 1.14.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.
package/dist/index.d.ts CHANGED
@@ -3,18 +3,18 @@ import { VERSION } from "./version.js";
3
3
  /**
4
4
  * npm package name that TanStack Intent discovers as a skill source.
5
5
  */
6
- declare const PACKAGE_NAME: "@arcjet/skills";
6
+ export declare const PACKAGE_NAME: "@arcjet/skills";
7
7
  /**
8
8
  * Leaf skill names shipped in this package. Each matches
9
9
  * `skills/<name>/SKILL.md`.
10
10
  */
11
- type SkillName = "choose-protections" | "cli" | "guard" | "mcp" | "protect";
11
+ export type SkillName = "choose-protections" | "cli" | "guard" | "mcp" | "protect";
12
12
  /**
13
13
  * Static manifest for one shipped skill. Intent reads the `SKILL.md` files
14
14
  * themselves; this export is for TypeScript consumers who want identities
15
15
  * without scanning `node_modules`.
16
16
  */
17
- interface SkillManifest {
17
+ export interface SkillManifest {
18
18
  readonly name: SkillName;
19
19
  /**
20
20
  * When to load this skill. Kept in sync with the `SKILL.md` description.
@@ -34,18 +34,18 @@ interface SkillManifest {
34
34
  * Skills shipped in this package version. Load only the entry that matches
35
35
  * the current task (`@arcjet/skills#<name>`).
36
36
  */
37
- declare const skills: readonly SkillManifest[];
37
+ export declare const skills: readonly SkillManifest[];
38
38
  /**
39
39
  * Format a TanStack Intent load identity (`@arcjet/skills#protect`).
40
40
  */
41
- declare function skillIdentity(name: SkillName): string;
41
+ export declare function skillIdentity(name: SkillName): string;
42
42
  /**
43
43
  * Look up one shipped skill by leaf name.
44
44
  */
45
- declare function getSkill(name: SkillName): SkillManifest | undefined;
45
+ export declare function getSkill(name: SkillName): SkillManifest | undefined;
46
46
  /**
47
47
  * Package version these skills were published with.
48
48
  */
49
- declare function skillLibraryVersion(): string;
49
+ export declare function skillLibraryVersion(): string;
50
50
  //#endregion
51
- export { PACKAGE_NAME, SkillManifest, SkillName, VERSION, getSkill, skillIdentity, skillLibraryVersion, skills };
51
+ export { VERSION };
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ const PACKAGE_NAME = "@arcjet/skills";
11
11
  const skills = [
12
12
  {
13
13
  name: "protect",
14
- description: "Add Arcjet request protection to JavaScript and TypeScript HTTP handlers. Use when protecting Next.js, Express, Fastify, SvelteKit, Remix, Astro, Nuxt, Bun, Deno, NestJS, or Node.js routes with rate limiting, bot detection, Shield, email validation, or sensitive info detection.",
14
+ description: "Add Arcjet request protection to JavaScript and TypeScript HTTP handlers. Use when protecting Next.js, Express, Fastify, SvelteKit, Remix, React Router, Hono, Astro, Nuxt, Bun, Deno, NestJS, or Node.js routes with rate limiting, bot detection, Shield, email validation, or sensitive info detection.",
15
15
  file: "skills/protect/SKILL.md",
16
16
  sources: ["docs/protect.md"]
17
17
  },
package/dist/version.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  //#region src/version.d.ts
2
2
  /** Package version. Updated by the release process. */
3
- declare const VERSION: string;
4
- //#endregion
5
- export { VERSION };
3
+ export declare const VERSION: string;
4
+ //#endregion
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.ts
2
2
  /** Package version. Updated by the release process. */
3
- const VERSION = "1.12.0";
3
+ const VERSION = "1.14.0";
4
4
  //#endregion
5
5
  export { VERSION };
@@ -68,3 +68,10 @@ rate limiting.
68
68
 
69
69
  **Rule:** `filter` (request-based only). Can also be a remote rule via CLI or
70
70
  MCP.
71
+
72
+ ## Claude Code / Copilot (no application SDK)
73
+
74
+ Not `protect()` or `@arcjet/guard`. Publish a coding-agent policy attached
75
+ to **Execute on** (Tool call, Prompt, or Model switch) via `@arcjet/skills#mcp`, then
76
+ install HTTP hooks from https://docs.arcjet.com/coding-agents. Copy the
77
+ templates: the hook URL must not name a policy and must omit `?surface=`.
package/docs/guard.md CHANGED
@@ -11,6 +11,10 @@ MCP server handlers, queue workers, and background jobs.
11
11
  The word "server" on MCP is misleading. MCP tools are invoked over stdio or
12
12
  SSE and do not receive an HTTP request.
13
13
 
14
+ Claude Code / Copilot HTTP hooks are not `@arcjet/guard`. Author the
15
+ policy via MCP and install hooks from https://docs.arcjet.com/coding-agents
16
+ (omit `?surface=`). **Execute on** is Tool call, Prompt, or Model switch.
17
+
14
18
  ## Client
15
19
 
16
20
  ```ts
@@ -32,13 +36,15 @@ Declare rules at module scope so `.deniedResult(decision)` and
32
36
  Call `guard()` where you already know the operation. Hardcode the `label`.
33
37
  Do not interpolate names in a generic dispatcher.
34
38
 
35
- Labels are slugs: lowercase letters, digits, dash, and dot only; must start
36
- and end with a letter or digit; max 256 bytes. Use `tools.get-weather`, not
37
- `tools.get_weather`. Metadata keys may contain underscores; labels and
38
- rate-limit `bucket` names may not.
39
+ Hardcode labels as slugs: lowercase letters, digits, `-`, `.`, and `_`
40
+ (`tools.get-weather`). Start and end with a letter or digit; max 256 bytes.
41
+ Prefer dash/dot in new labels. Do not interpolate user input. Check a label
42
+ you build yourself with `validateGuardLabel` — a slug the service will not
43
+ match reads as `ALLOW` with `hasFailedOpen()` false.
39
44
 
40
45
  ```ts
41
- const decision = await arcjet.guard("tools.get-weather", {
46
+ const decision = await arcjet.guard({
47
+ label: "tools.get-weather",
42
48
  rules: [/* ... */],
43
49
  metadata: { user: { id: userId } },
44
50
  });
@@ -103,6 +109,7 @@ Prefer the versioned Guard namespaces over hand-wrapping every tool:
103
109
  | Google ADK JS | `@arcjet/guard/google-adk/v2` |
104
110
  | Strands Agents JS | `@arcjet/guard/strands-agents/v1` |
105
111
  | TanStack AI | `@arcjet/guard/tanstack-ai/v0` |
112
+ | Cloudflare Think | `@arcjet/guard/cloudflare-think/v0` |
106
113
 
107
114
  Unversioned aliases do not resolve. Load the matching
108
115
  `@arcjet/guard#integrate-arcjet-guard-*` skill for the integration you are
@@ -114,8 +121,16 @@ Framework wrappers fail closed by default when Guard is unavailable. Core
114
121
  JS LangChain `createAgent` is `@arcjet/guard/langchain/v1`, not LangGraph.
115
122
  JS Google ADK is `guardPlugin` on the Runner — there is no `guardTool`.
116
123
  TanStack AI is `guardMiddleware` — do not use `guardTool` (an `execute`
117
- throw is swallowed). JS Strands Agents is official `@strands-agents/sdk`,
118
- not Python `strands`.
124
+ throw is swallowed). Cloudflare Think is `guardHooks` on
125
+ `beforeToolCall` — default DENY is substitute. JS Strands Agents is
126
+ official `@strands-agents/sdk`, not Python `strands`.
127
+
128
+ Every JS wrapper policy accepts optional `actor` and `inputs` (static values
129
+ or a resolver over that adapter's native call — parsed input plus trusted
130
+ runtime/context, like Vercel AI's `(input, ctx)`). Build each
131
+ input with `policyInput` so a remote policy that declares those names can
132
+ evaluate. Omit them and the remote policy has nothing to read — its rules do
133
+ not fire.
119
134
 
120
135
  Every adapter uses one `ArcjetDenialResult` payload
121
136
  (`{ arcjetDenied: true, reason, message, retryable }`). Delivery is
@@ -123,7 +138,8 @@ per-framework: return the object (AI SDK, Mastra, OpenAI Agents, Genkit
123
138
  `toolResponse.output`, LangGraph, LangChain `guardTool`, Google ADK plugin
124
139
  dict, Strands `guardTool`); wrap it (Claude Agent SDK `isError: true`,
125
140
  LangChain `guardMiddleware` `ToolMessage`, Strands `guardHooks` cancel
126
- string, TanStack `onBeforeToolCall` skip); or throw `ArcjetDeniedError`
141
+ string, TanStack `onBeforeToolCall` skip, Cloudflare Think
142
+ `beforeToolCall` substitute); or throw `ArcjetDeniedError`
127
143
  (Eve, unless `onDeny: "result"`). A throw from a return-style adapter
128
144
  drops the fields.
129
145
 
package/docs/mcp.md CHANGED
@@ -66,9 +66,12 @@ Add a custom connector named `Arcjet` with URL `https://api.arcjet.com/mcp`.
66
66
 
67
67
  OAuth. The first connection redirects to sign in with an Arcjet account.
68
68
 
69
+ Agent registration (the agent registers for its own identity): follow https://arcjet.com/auth.md — do not invent that ceremony.
70
+
69
71
  ## Common workflows
70
72
 
71
73
  - Bootstrap: `list-teams` → `list-sites` → `get-site-key` → write `ARCJET_KEY`
72
74
  - Investigate: `analyze-traffic` → `list-requests` → `investigate-ip`
73
75
  - Remote rules: `create-rule` (DRY_RUN) → `get-dry-run-impact` → `promote-rule`
76
+ - Guard policies: `list-guard-policies` → `describe-guard-policy` → `validate-guard-policy` → `put-guard-policy`. Authoring is MCP-only; the CLI has no policy commands. Application policies select by `label` / wrapper `action`. Coding-agent policies attach by **Execute on** (Tool call, Prompt, or Model switch), not by label. Install Claude Code / Copilot HTTP hooks from https://docs.arcjet.com/coding-agents — copy the templates. The hook URL must not name a policy and must omit `?surface=` (managed settings reach CLI, IDE, Desktop, and cloud; a hard-coded `cli` mislabels most traffic).
74
77
  - Briefing: `get-security-briefing`
package/docs/protect.md CHANGED
@@ -156,9 +156,10 @@ values are rejected. Syntax validation does not prove provenance.
156
156
  Never silence an `unverified-header` warning by copying `X-Forwarded-For` (or
157
157
  another client-controlled header) into `ipSrc`. That relabels attacker input
158
158
  as trusted. Inspect representative requests with
159
- `client.clientIpDetails(request)` in `@arcjet/node`, or `findIpDetails()` /
160
- `resolveClientIp()` from `@arcjet/ip`. Check `ip`, `provenance`, `verified`,
161
- and `header`. These diagnostics do not consume the once-per-client warning.
159
+ `aj.clientIpDetails(request)` on the constructed `@arcjet/node` client, or
160
+ `findIpDetails()` / `resolveClientIp()` from `@arcjet/ip`. Check `ip`,
161
+ `provenance`, `verified`, and `header`. These diagnostics do not consume
162
+ the once-per-client warning.
162
163
 
163
164
  `protect()` accepts nested-JSON `metadata`. It does not affect fingerprinting.
164
165
  Do not put secrets or PII in it. When present, request decisions also expose
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcjet/skills",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "Versioned Agent Skills for the Arcjet JavaScript SDK, shipped with TanStack Intent",
5
5
  "keywords": [
6
6
  "agent-skills",
@@ -56,9 +56,9 @@
56
56
  "test": "npm run build && npm run test-coverage && npm run validate-skills && node ../.github/scripts/check-skill-source-stale.mjs"
57
57
  },
58
58
  "devDependencies": {
59
- "@tanstack/intent": "0.3.8",
60
- "@types/node": "22.20.1",
61
- "tsdown": "0.22.14",
59
+ "@tanstack/intent": "0.4.0",
60
+ "@types/node": "22.20.4",
61
+ "tsdown": "0.23.0",
62
62
  "typescript": "7.0.2"
63
63
  },
64
64
  "engines": {
@@ -7,7 +7,7 @@ metadata:
7
7
  author: arcjet
8
8
  type: core
9
9
  library: "@arcjet/skills"
10
- library_version: "1.12.0" # x-release-please-version
10
+ library_version: "1.14.0" # x-release-please-version
11
11
  sources:
12
12
  - docs/choose-protections.md
13
13
  ---
@@ -42,3 +42,8 @@ entities never match without `backend: rampart()`.
42
42
 
43
43
  Remote bot and filter rules can be managed with the CLI or MCP without a
44
44
  redeploy — load `@arcjet/skills#cli` or `@arcjet/skills#mcp`.
45
+
46
+ Claude Code / Copilot hooks are not this table. Publish a coding-agent
47
+ policy via `@arcjet/skills#mcp` (**Execute on**: Tool call, Prompt, or
48
+ Model switch) and install hooks from
49
+ https://docs.arcjet.com/coding-agents (omit `?surface=`).
@@ -7,7 +7,7 @@ metadata:
7
7
  author: arcjet
8
8
  type: core
9
9
  library: "@arcjet/skills"
10
- library_version: "1.12.0" # x-release-please-version
10
+ library_version: "1.14.0" # x-release-please-version
11
11
  sources:
12
12
  - docs/cli.md
13
13
  ---
@@ -2,12 +2,12 @@
2
2
  name: guard
3
3
  description: "Add Arcjet Guard to non-HTTP JavaScript: agent tool calls, MCP handlers, queue workers, and background jobs. Use when there is no HTTP request object, or when the user asks to guard tools, rate-limit agent actions, or block prompt injection on tool arguments."
4
4
  license: Apache-2.0
5
- compatibility: JavaScript and TypeScript apps using @arcjet/guard on Node.js >= 22.
5
+ compatibility: JavaScript and TypeScript apps using @arcjet/guard on Node.js >=22.21.0 <23 || >=24.5.0.
6
6
  metadata:
7
7
  author: arcjet
8
8
  type: core
9
9
  library: "@arcjet/skills"
10
- library_version: "1.12.0" # x-release-please-version
10
+ library_version: "1.14.0" # x-release-please-version
11
11
  sources:
12
12
  - docs/guard.md
13
13
  ---
@@ -20,8 +20,13 @@ and agent tool calls are Guard. HTTP routes are `@arcjet/skills#protect`.
20
20
  For a specific vendor SDK, load the matching skill from `@arcjet/guard`
21
21
  (`@arcjet/guard#integrate-arcjet-guard-agents`, `-eve`, `-mastra`,
22
22
  `-langgraph`, `-langchain`, `-openai-agents`, `-genkit`, `-google-adk`,
23
- `-strands-agents`, `-tanstack-ai`, `-claude-agent-sdk`,
24
- `-claude-managed-agents`).
23
+ `-strands-agents`, `-tanstack-ai`, `-cloudflare-think`,
24
+ `-claude-agent-sdk`, `-claude-managed-agents`).
25
+
26
+ Claude Code / Copilot HTTP hooks are not this package. Publish a
27
+ coding-agent policy via `@arcjet/skills#mcp` (**Execute on**: Tool call,
28
+ Prompt, or Model switch) and install hooks from
29
+ https://docs.arcjet.com/coding-agents (omit `?surface=`).
25
30
 
26
31
  ## Client
27
32
 
@@ -38,11 +43,14 @@ Declare rules at module scope so `.deniedResult(decision)` works.
38
43
 
39
44
  Hardcode the `label`. Do not interpolate in a generic dispatcher.
40
45
 
41
- Labels: lowercase letters, digits, `-`, `.` only; start and end with a letter
42
- or digit. `tools.get-weather`, not `tools.get_weather`.
46
+ Hardcode labels as slugs: lowercase letters, digits, `-`, `.`, and `_`
47
+ (`tools.get-weather`). Start and end with a letter or digit; max 256 bytes.
48
+ Prefer dash/dot in new labels. Check a label you build yourself with
49
+ `validateGuardLabel`.
43
50
 
44
51
  ```ts
45
- const decision = await arcjet.guard("tools.get-weather", {
52
+ const decision = await arcjet.guard({
53
+ label: "tools.get-weather",
46
54
  rules: [/* ... */],
47
55
  metadata: { user: { id: userId } },
48
56
  });
@@ -77,6 +85,12 @@ Wrappers fail closed by default. HITL (`needsApproval`, `interrupt()`,
77
85
  `requireConfirmation`, `canUseTool`) is not a policy gate; Guard still runs
78
86
  after a human yes.
79
87
 
88
+ Every wrapper policy accepts optional `actor` and `inputs` (static or a
89
+ resolver over that adapter's native call — parsed input plus trusted
90
+ runtime/context) so a remote policy that declares those names can evaluate. Build
91
+ each input with `policyInput`. Omit them and the remote policy has nothing
92
+ to read — its rules do not fire.
93
+
80
94
  Google ADK is `guardPlugin` (no `guardTool`). TanStack AI is
81
95
  `guardMiddleware` (do not wrap `execute`). LangChain `createAgent` is
82
96
  `/langchain/v1`, not LangGraph.
@@ -7,7 +7,7 @@ metadata:
7
7
  author: arcjet
8
8
  type: core
9
9
  library: "@arcjet/skills"
10
- library_version: "1.12.0" # x-release-please-version
10
+ library_version: "1.14.0" # x-release-please-version
11
11
  sources:
12
12
  - docs/mcp.md
13
13
  ---
@@ -39,6 +39,13 @@ claude mcp add arcjet --transport http https://api.arcjet.com/mcp
39
39
  ```
40
40
 
41
41
  Bootstrap: `list-teams` → `list-sites` → `get-site-key` → write `ARCJET_KEY`.
42
+ Agent identity (not human browser OAuth): follow https://arcjet.com/auth.md.
42
43
  Investigate: `analyze-traffic`, `list-requests`, `list-guards`,
43
44
  `investigate-ip`. Remote rules: `create-rule` (DRY_RUN) →
44
- `get-dry-run-impact` → `promote-rule`.
45
+ `get-dry-run-impact` → `promote-rule`. Guard policies (MCP-only; no CLI
46
+ commands): `list-guard-policies` → `describe-guard-policy` →
47
+ `validate-guard-policy` → `put-guard-policy`. Application policies select by
48
+ `label` / `action`. Coding-agent policies attach by **Execute on** (Tool call,
49
+ Prompt, or Model switch). Install Claude Code / Copilot hooks from
50
+ https://docs.arcjet.com/coding-agents — copy the templates. The hook URL
51
+ must not name a policy and must omit `?surface=`.
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: protect
3
- description: Add Arcjet request protection to JavaScript and TypeScript HTTP handlers. Use when protecting Next.js, Express, Fastify, SvelteKit, Remix, Astro, Nuxt, Bun, Deno, NestJS, or Node.js routes with rate limiting, bot detection, Shield, email validation, or sensitive info detection.
3
+ description: Add Arcjet request protection to JavaScript and TypeScript HTTP handlers. Use when protecting Next.js, Express, Fastify, SvelteKit, Remix, React Router, Hono, Astro, Nuxt, Bun, Deno, NestJS, or Node.js routes with rate limiting, bot detection, Shield, email validation, or sensitive info detection.
4
4
  license: Apache-2.0
5
5
  compatibility: JavaScript and TypeScript HTTP apps using an @arcjet/* framework adapter.
6
6
  metadata:
7
7
  author: arcjet
8
8
  type: core
9
9
  library: "@arcjet/skills"
10
- library_version: "1.12.0" # x-release-please-version
10
+ library_version: "1.14.0" # x-release-please-version
11
11
  sources:
12
12
  - docs/protect.md
13
13
  ---
@@ -94,7 +94,7 @@ input as trusted.
94
94
  When no usable public address is available, adapters may fall back to
95
95
  forwarding headers and log one `unverified-header` warning per client.
96
96
  Configure `proxies` (or `cloudflare()`). Inspect with
97
- `clientIpDetails()` (`@arcjet/node`) or `findIpDetails()` /
97
+ `aj.clientIpDetails(request)` (`@arcjet/node`) or `findIpDetails()` /
98
98
  `resolveClientIp()` (`@arcjet/ip`) before shipping.
99
99
 
100
100
  Nested `metadata` is for the Console — no secrets, no PII.