feat(guard): add Claude Agent SDK support as @arcjet/guard/claude-agent-sdk/v0 - #6229
feat(guard): add Claude Agent SDK support as @arcjet/guard/claude-agent-sdk/v0#6229davidmytton wants to merge 4 commits into
Conversation
…nt-sdk/v0 Add a versioned @arcjet/guard subpath for the Claude Agent SDK: guardTool for authored tool() handlers, guardHooks for UserPromptSubmit / PreToolUse / PostToolUse, and claudeAgentContext that reads session_id and never mints a correlation id. The SDK is an optional type-only peer so CI passes when it is absent from node_modules. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
|
Cursor Agent can help with this pull request. Just |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Arcjet Review — 🟡 Medium Risk
Decision: Needs Review
Rationale: New Claude Agent SDK namespace added following the exact pattern of existing mastra/v1 and vercel-eve/v0 namespaces. Additive-only: new export path, new source files, new tests. Optional peer dependency is correctly declared, CI verifies the peer is only used for types, renovate config restricts to <1 with automerge disabled. Fail-closed by default. Correlation IDs are validated and never minted. Double-wrap defense via shared symbol. Extensive test coverage including unavailability, denial shape, hook wiring, type-only imports, and package export map. Dependency and CI escalation triggers fired but the changes are well-scoped and consistent with prior integrations, so approving despite Medium risk.
Summary of Changes
Adds a new @arcjet/guard/claude-agent-sdk/v0 namespace exporting guardTool, guardHooks, and claudeAgentContext for integrating Arcjet security policy into Claude Agent SDK agents. Includes an integration skill, updated docs, CI job to verify type-only peer usage, and renovate config for the new optional peer.
PR Title & Description
These do not match the changes on the branch. They did not change this review's decision, but they will withhold approval once the other findings are resolved. Update them, then add the ai-review label to re-run the review.
- description (missing): The PR description contains only the Cursor Cloud Agent boilerplate template and no description of what the branch changes. For a ~2000-line feature adding a new namespace, exports, docs, skill, CI job, and dependency, a future reader gets nothing beyond the title.
Suggested description
Adds `@arcjet/guard/claude-agent-sdk/v0`, a new vendor namespace that integrates Arcjet Guard with the Claude Agent SDK.
### What's exported
- `guardTool(client, tool, policy)` — wraps an authored `tool()` handler. On DENY the handler is not called and the model receives a `CallToolResult` with `isError: true` (never throws).
- `guardHooks(client, policy)` — Claude Agent SDK hooks:
- `UserPromptSubmit` screens inbound prompts (DENY → `{ decision: "block" }`). This is the only place to attach inbound rules; there is no `guardInbound`.
- `PreToolUse` gates built-ins and unwrapped MCP tools (DENY → `permissionDecision: "deny"`). `canUseTool` is intentionally not used — Claude skips it under `allowedTools`, allow rules, and `bypassPermissions` / `acceptEdits`.
- `PostToolUse` is capture-only.
- `claudeAgentContext(source, init)` — reads correlation from hook `session_id` or `options.sessionId`; never mints an id.
### Package & peer
- New export map entry `./claude-agent-sdk/v0` (no unversioned alias, no wildcard).
- `@anthropic-ai/claude-agent-sdk` added as an optional peer (`>=0.1.0 <1`) and a devDependency. Only type-only imports reach the SDK; a new CI job (`Unit tests with claude-agent-sdk absent`) enforces that by removing the peer and running the namespace tests.
- Renovate pinned to `<1` with automerge disabled — the SDK is pre-1.0 and tracks Claude Code patch-for-patch.
### Docs & skill
- README section documenting the namespace, fail-closed defaults, and peer install.
- New `integrate-arcjet-guard-claude-agent-sdk` skill for Claude Code integration sessions.
- CONTRIBUTING.md updated to describe the Claude Agent SDK's decision points.Escalation Triggers
- Dependency Changes: arcjet-guard/package.json adds @anthropic-ai/claude-agent-sdk as devDependency and optional peer
- CI/CD Pipeline: .github/workflows/guard.yml adds a new test job for the claude-agent-sdk-absent scenario
Notes
PR size is roughly 2000 lines — above the 1000-line threshold — but the shape is heavily test/docs (denial, gate, hooks, guard-tool, context, index, type-only, peer, assignability tests plus a 250-line SKILL.md), and each unit closely mirrors the existing mastra/v1 namespace, so it remained reviewable.
Path filtering: 1 file excluded by ignore paths. 24 of 25 files included in review.
Approval withheld: The PR title or description does not match the branch — see the "PR Title & Description" section. Update them, then add the ai-review label to re-run the review.
Review: 8a3bb568 | Model: anthropic/claude-opus-4-7 | Powered by Arcjet Review
CI runs `npm ci` with the pinned npm 12.0.1. The previous lockfile was written with npm 10 and failed sync checks for the @sveltejs/kit override and the new @anthropic-ai/claude-agent-sdk entry. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
…fineProperty A throwing rules/metadata/sessionId factory now follows onGuardError instead of crashing the tool. The wrapped handler is installed with defineProperty so a non-writable original descriptor cannot throw at wrap time. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Remove the repo-internal "do not add examples here" line from the README, and drop the Eve/Mastra approval comparison from the Claude Agent SDK skill. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Adds
@arcjet/guard/claude-agent-sdk/v0for the Claude Agent SDK: wrap authoredtool()handlers, screen inbound prompts, and deny unwrapped / built-in tools. Correlation is read fromsession_id/options.sessionId— never minted.canUseToolis not a policy gate.Full working demo: arcjet/examples#193.