playbook/outfitter-agents/plugins/outfitter/skills/claude-commands/references/sdk-integration.md

437 lines
8.0 KiB
Markdown

# SDK Integration Reference
Guide to using slash commands with the Claude Agent SDK.
## Overview
Custom slash commands are fully accessible through the Claude Agent SDK, enabling programmatic invocation and integration into automated workflows.
---
## Discovering Commands
Commands are listed in the system initialization message:
### TypeScript
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Hello",
options: { maxTurns: 1 }
})) {
if (message.type === "system" && message.subtype === "init") {
console.log("Available commands:", message.slash_commands);
// Example: ["/compact", "/clear", "/help", "/review", "/deploy"]
}
}
```
### Python
```python
import asyncio
from claude_agent_sdk import query
async def main():
async for message in query(
prompt="Hello",
options={"max_turns": 1}
):
if message.type == "system" and message.subtype == "init":
print("Available commands:", message.slash_commands)
asyncio.run(main())
```
---
## Invoking Commands
Send commands as prompt strings:
### TypeScript
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
// Basic invocation
for await (const message of query({
prompt: "/review",
options: { maxTurns: 3 }
})) {
if (message.type === "assistant") {
console.log("Review:", message.message);
}
}
// With arguments
for await (const message of query({
prompt: "/fix-issue 123",
options: { maxTurns: 5 }
})) {
if (message.type === "result") {
console.log("Fixed:", message.result);
}
}
```
### Python
```python
async def main():
# Basic invocation
async for message in query(
prompt="/review",
options={"max_turns": 3}
):
if message.type == "assistant":
print("Review:", message.message)
# With arguments
async for message in query(
prompt="/fix-issue 123",
options={"max_turns": 5}
):
if message.type == "result":
print("Fixed:", message.result)
```
---
## Enabling Filesystem Settings
By default, the SDK doesn't read filesystem settings. Enable them explicitly:
### TypeScript
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "/my-custom-command",
options: {
maxTurns: 3,
settingSources: ['user', 'project', 'local'] // Enable filesystem
}
})) {
// Process results
}
```
### Python
```python
async for message in query(
prompt="/my-custom-command",
options={
"max_turns": 3,
"setting_sources": ["user", "project", "local"]
}
):
# Process results
```
**Setting Sources**:
- `user` - Personal settings (`~/.claude/`)
- `project` - Project settings (`.claude/`)
- `local` - Local overrides
---
## Built-in Commands
### /compact
Summarize conversation history to reduce context:
```typescript
for await (const message of query({
prompt: "/compact",
options: { maxTurns: 1 }
})) {
if (message.type === "system" && message.subtype === "compact_boundary") {
console.log("Compacted");
console.log("Pre-tokens:", message.compact_metadata.pre_tokens);
}
}
```
### /clear
Start fresh conversation:
```typescript
for await (const message of query({
prompt: "/clear",
options: { maxTurns: 1 }
})) {
if (message.type === "system" && message.subtype === "init") {
console.log("Cleared, new session:", message.session_id);
}
}
```
---
## Workflow Automation
### Sequential Commands
Chain commands for multi-step workflows:
```typescript
async function developmentWorkflow(featureName: string) {
// Step 1: Create branch
for await (const msg of query({
prompt: `/create-branch ${featureName}`,
options: { maxTurns: 3 }
})) {
// Handle branch creation
}
// Step 2: Implement feature
for await (const msg of query({
prompt: `/implement ${featureName}`,
options: { maxTurns: 10 }
})) {
// Handle implementation
}
// Step 3: Create PR
for await (const msg of query({
prompt: "/create-pr",
options: { maxTurns: 3 }
})) {
// Handle PR creation
}
}
```
### Conditional Execution
Execute commands based on results:
```typescript
async function deployIfTestsPass() {
let testsPass = false;
for await (const msg of query({
prompt: "/run-tests",
options: { maxTurns: 5 }
})) {
if (msg.type === "result" && msg.result.includes("All tests passed")) {
testsPass = true;
}
}
if (testsPass) {
for await (const msg of query({
prompt: "/deploy staging",
options: { maxTurns: 5 }
})) {
// Handle deployment
}
}
}
```
---
## Error Handling
### Command Not Found
```typescript
for await (const msg of query({
prompt: "/nonexistent-command",
options: { maxTurns: 1 }
})) {
if (msg.type === "error") {
console.error("Command error:", msg.error);
}
}
```
### Timeout Handling
```typescript
import { query } from "@anthropic-ai/claude-agent-sdk";
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 60000);
try {
for await (const msg of query({
prompt: "/long-running-command",
options: { maxTurns: 10 },
signal: controller.signal
})) {
// Process messages
}
} finally {
clearTimeout(timeout);
}
```
---
## SlashCommand Tool
Claude can programmatically invoke commands via the SlashCommand tool:
### Enabling
Commands with `description` are automatically available to the SlashCommand tool.
### Disabling
Prevent automatic invocation:
```yaml
---
description: Interactive deployment (manual only)
disable-model-invocation: true
---
```
### Character Budget
Control how many command descriptions fit in context:
```bash
export SLASH_COMMAND_TOOL_CHAR_BUDGET=30000 # Default: 15000
```
---
## Integration Patterns
### CI/CD Pipeline
```typescript
// GitHub Actions integration
async function runCodeQuality() {
const results = [];
for await (const msg of query({
prompt: "/lint && /test && /security-check",
options: { maxTurns: 10 }
})) {
if (msg.type === "result") {
results.push(msg.result);
}
}
return results;
}
```
### Chatbot Integration
```typescript
// Slack/Discord bot
async function handleUserCommand(userMessage: string) {
if (userMessage.startsWith("/")) {
for await (const msg of query({
prompt: userMessage,
options: { maxTurns: 5 }
})) {
if (msg.type === "assistant") {
await sendToChannel(msg.message);
}
}
}
}
```
### Batch Processing
```typescript
// Process multiple items
async function batchReview(files: string[]) {
for (const file of files) {
for await (const msg of query({
prompt: `/review-file ${file}`,
options: { maxTurns: 3 }
})) {
if (msg.type === "result") {
await saveReview(file, msg.result);
}
}
}
}
```
---
## Best Practices
### 1. Enable Settings Explicitly
Always specify which settings to load:
```typescript
options: {
settingSources: ['user', 'project', 'local']
}
```
### 2. Handle All Message Types
Check for various response types:
```typescript
for await (const msg of query({ prompt: "/command" })) {
switch (msg.type) {
case "assistant":
// Claude's response
break;
case "result":
// Command result
break;
case "error":
// Error occurred
break;
case "system":
// System message
break;
}
}
```
### 3. Set Appropriate Timeouts
Long-running commands need timeout handling:
```typescript
options: {
maxTurns: 10,
timeout: 120000 // 2 minutes
}
```
### 4. Use maxTurns Appropriately
Simple commands need fewer turns:
```typescript
// Simple lookup
options: { maxTurns: 1 }
// Standard operation
options: { maxTurns: 3 }
// Complex workflow
options: { maxTurns: 10 }
```
---
## Resources
- [Claude Agent SDK Documentation](https://platform.claude.com/docs/en/agent-sdk/overview)
- [TypeScript SDK Reference](https://platform.claude.com/docs/en/agent-sdk/typescript)
- [Python SDK Reference](https://platform.claude.com/docs/en/agent-sdk/python)