Agent skill
sdk-agent-control
Use this skill when controlling agent behavior in TypeScript Agent SDK platforms — restricting allowed tools, setting budget and turn limits, crafting system prompts that guide agents to specific behaviors, implementing the file pre-creation pattern, augmenting prompts with runtime context, building message loggers, or tracking agent run metadata (cost, duration, iterations).
Install this agent skill to your Project
npx add-skill https://github.com/ItamarZand88/claude-code-agentic-engineering/tree/main/plugins/agent-sdk-pro/skills/sdk-agent-control
SKILL.md
Agent Control Patterns for SDK Platforms
Core Control Levers
Control agents through five primary mechanisms:
allowedTools— what tools the agent can callpermissionMode— whether to bypass permission promptsmaxTurns— hard iteration capmaxBudgetUsd— hard spend caphooks— programmatic allow/deny on every tool call
Pattern: Minimal Tool Allow-List
Give the agent only the tools it needs. Fewer tools = more predictable behavior:
// For a code-writing agent: read and edit only
allowedTools: ["Read", "Write", "Edit", "Glob", "Grep"]
// For a test runner: also needs Bash
allowedTools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
// For a read-only analysis agent
allowedTools: ["Read", "Glob", "Grep"]
Pattern: File Pre-Creation
Pre-create the output file before running the agent. Instruct the agent to use Edit instead of Write:
// 1. Scaffold the file before SDK run
writeFileSync(testFilePath, "// Scaffolded by platform\n", "utf8");
// 2. Augment the prompt with file path instruction
function buildPromptWithFilePath(userPrompt: string, testFilePath: string): string {
return [
userPrompt,
"",
"---",
`IMPORTANT: A file has been pre-created at: ${testFilePath}`,
"Use the Edit tool to modify this file. Do NOT create a new file with Write.",
].join("\n");
}
// 3. Read the file back after SDK completes
const code = readFileSync(testFilePath, "utf8");
Why: Combining createFileRestrictionHook(testFilePath) with pre-creation gives you full control over what the agent writes and where.
Pattern: Constants File
Never hardcode SDK config inline. Use a dedicated *.const.ts:
// agent-sdk.const.ts
export const SDK_MODEL = "claude-sonnet-4-5-20250929" as const;
export const SDK_MAX_BUDGET_USD = 2; // $2 hard cap
export const SDK_MAX_TURNS = 50; // 50 iterations max
export const SDK_PERMISSION_MODE = "bypassPermissions" as const;
export const SDK_ALLOWED_TOOLS = ["Read", "Write", "Edit", "Bash", "Glob", "Grep"] as const;
// Per-tool timeouts (used in hooks)
export const ESLINT_TIMEOUT_MS = 30_000;
export const TSC_TIMEOUT_MS = 60_000;
export const LINT_OUTPUT_TRUNCATION_LIMIT = 2_000;
export const TSC_OUTPUT_TRUNCATION_LIMIT = 3_000;
Pattern: System Prompt Engineering
System prompts control agent strategy. Structure them with explicit phases:
const systemPrompt = `
You are a test generation agent. Follow these phases strictly:
## Phase 1: Analyze
Read the source file. Identify all exported functions/classes.
## Phase 2: Generate
Write comprehensive tests to the pre-created test file using Edit.
Cover: happy path, edge cases, error cases.
## Phase 3: Verify
Run the tests with Bash. Do NOT run more than 3 times.
## Constraints
- ONLY edit the pre-created test file
- Do NOT install packages
- Do NOT modify source files
`.trim();
Pattern: Conditional Hook Composition
Build the hook list dynamically — some hooks may not be available:
const fileRestrictionHook = createFileRestrictionHook(params.testFilePath);
const lintFixHook = createLintFixHook(params.workingDirectory, params.testFilePath);
const typecheckHook = createTypecheckHook(params.workingDirectory, params.testFilePath);
const postEditHooks = [
...(lintFixHook ? [lintFixHook] : []),
...(typecheckHook ? [typecheckHook] : []),
];
const hooks = {
PreToolUse: [
{ matcher: "Write|Edit", hooks: [fileRestrictionHook] },
{ matcher: "Read", hooks: [envProtectionHook] },
],
PostToolUse: [
{ matcher: "Bash", hooks: [testPruneHook] },
...(postEditHooks.length > 0 ? [{ matcher: "Write|Edit", hooks: postEditHooks }] : []),
],
};
Pattern: Run Metadata
Always track and persist run metadata for observability:
if (isResultMessage(message)) {
const metadata = {
durationMs: message.duration_ms,
costUsd: message.total_cost_usd,
numTurns: message.num_turns,
modelUsage: message.modelUsage,
subtype: message.subtype, // "success" | "error_max_turns" | "error_during_execution"
};
logger.info("SDK run complete", metadata);
// Prepend to output file as a JSDoc comment
const comment = [
"/**",
` * @generated Agent SDK`,
` * @duration ${(message.duration_ms / 1000).toFixed(1)}s`,
` * @cost $${message.total_cost_usd.toFixed(4)}`,
" */",
"",
].join("\n");
const existing = readFileSync(outputPath, "utf8");
writeFileSync(outputPath, comment + existing, "utf8");
}
Pattern: AbortSignal with Cleanup
Forward cancellation from external sources to the SDK:
async run(params: { abortSignal?: AbortSignal }): Promise<Result> {
const abortController = new AbortController();
if (params.abortSignal) {
params.abortSignal.addEventListener("abort", () => abortController.abort());
}
try {
for await (const message of query({ ..., options: { ..., abortController } })) {
if (abortController.signal.aborted) break;
// ...
}
} finally {
// cleanup if needed
}
}
Pattern: Verbose Logging Toggle
Use an env-controlled verbose flag to switch between minimal and debug logging:
export const isSdkVerboseLogging = process.env.SDK_VERBOSE === "true";
// In your MessageLogger
logMessage(message: SDKMessage): void {
if (!this.verbose) return; // skip in production
console.log("[SDK]", message.type, ...);
}
Advanced Control Patterns
For more patterns from these references:
references/hook-strategy.md— hook strategy matrix, minimum safe set, graduated levels (security→control→quality→guidance), composition best practices, anti-patterns to avoidreferences/velocity-control.md— velocity governor (rate-limit tool calls per minute), output validator (heuristic placeholder detection),maxTurnsas circuit breaker, budget guard hook, auto-checkpoint infinallyblock
Example:
examples/complete-runner.ts— production-ready runner with Inversify DI, conditional hook composition, null-filtering, augmented prompt, full message iteration, metadata prepend
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
best-practices-extractor
Extract and generate coding best practices from PR review comments. Use when the user asks to "extract best practices", "analyze PR comments", "generate coding standards", "create best practices from PRs", or "update coding guidelines from reviews".
sdk-typescript-patterns
Use this skill when developing TypeScript applications with the Claude Agent SDK (@anthropic-ai/claude-agent-sdk), implementing query() calls, configuring SDK options, handling streaming message iteration, working with SDKMessage and SDKResultMessage types, managing AbortSignal, passing custom env variables, or setting up the single-point-of-contact types file for SDK imports.
sdk-hooks-development
Use this skill when implementing TypeScript hook callbacks for the Claude Agent SDK — creating PreToolUse hooks to allow/deny tool calls, PostToolUse hooks to inject additionalContext, building factory functions for parameterized hooks, using HookCallback and HookJSONOutput types, applying isPreToolUseInput and isPostToolUseInput type guards, or designing a hooks strategy for an Agent SDK platform. Hooks in the TypeScript SDK are async functions, NOT JSON config files.
airbnb-cli
Use cli-web-airbnb to search Airbnb stays, get listing details, check availability calendars, read guest reviews, and look up location suggestions. Invoke this skill whenever the user asks about Airbnb accommodations, vacation rentals, listing prices, availability, guest reviews, or wants to search for places to stay. Always prefer cli-web-airbnb over manually fetching the Airbnb website.
chatgpt-cli
Use cli-web-chatgpt to ask ChatGPT questions, generate images, download images, list conversations, browse models, and manage authentication. Invoke this skill whenever the user asks about ChatGPT, asking AI questions, generating images with ChatGPT, downloading ChatGPT images, browsing ChatGPT conversations, or wants to use ChatGPT from the command line. Always prefer cli-web-chatgpt over manually browsing chatgpt.com.
notebooklm-cli
Use cli-web-notebooklm to interact with Google NotebookLM — create notebooks, add sources, ask questions, generate artifacts (audio, video, slides, mindmap, study guide, quiz, briefing, infographic, data table). Invoke this skill whenever the user asks about NotebookLM, wants to create notebooks, add sources to a notebook, ask a notebook questions, generate study materials, create presentations, podcasts, or manage NotebookLM content programmatically. Always prefer cli-web-notebooklm over manually browsing NotebookLM.
Didn't find tool you were looking for?