opencode-skills-antigravity 1.0.4 → 1.0.6
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/bundled-skills/ad-creative/SKILL.md +371 -0
- package/bundled-skills/ad-creative/evals/evals.json +90 -0
- package/bundled-skills/ad-creative/references/generative-tools.md +637 -0
- package/bundled-skills/ad-creative/references/platform-specs.md +213 -0
- package/bundled-skills/ai-seo/SKILL.md +407 -0
- package/bundled-skills/ai-seo/evals/evals.json +90 -0
- package/bundled-skills/ai-seo/references/content-patterns.md +285 -0
- package/bundled-skills/ai-seo/references/platform-ranking-factors.md +152 -0
- package/bundled-skills/backend-dev-guidelines/SKILL.md +1 -1
- package/bundled-skills/cc-skill-security-review/SKILL.md +1 -1
- package/bundled-skills/churn-prevention/SKILL.md +433 -0
- package/bundled-skills/churn-prevention/evals/evals.json +93 -0
- package/bundled-skills/churn-prevention/references/cancel-flow-patterns.md +316 -0
- package/bundled-skills/churn-prevention/references/dunning-playbook.md +408 -0
- package/bundled-skills/claude-api/LICENSE.txt +202 -0
- package/bundled-skills/claude-api/SKILL.md +252 -0
- package/bundled-skills/claude-api/csharp/claude-api.md +70 -0
- package/bundled-skills/claude-api/curl/examples.md +164 -0
- package/bundled-skills/claude-api/go/claude-api.md +146 -0
- package/bundled-skills/claude-api/java/claude-api.md +128 -0
- package/bundled-skills/claude-api/php/claude-api.md +88 -0
- package/bundled-skills/claude-api/python/agent-sdk/README.md +269 -0
- package/bundled-skills/claude-api/python/agent-sdk/patterns.md +319 -0
- package/bundled-skills/claude-api/python/claude-api/README.md +404 -0
- package/bundled-skills/claude-api/python/claude-api/batches.md +182 -0
- package/bundled-skills/claude-api/python/claude-api/files-api.md +162 -0
- package/bundled-skills/claude-api/python/claude-api/streaming.md +162 -0
- package/bundled-skills/claude-api/python/claude-api/tool-use.md +587 -0
- package/bundled-skills/claude-api/ruby/claude-api.md +87 -0
- package/bundled-skills/claude-api/shared/error-codes.md +205 -0
- package/bundled-skills/claude-api/shared/live-sources.md +121 -0
- package/bundled-skills/claude-api/shared/models.md +68 -0
- package/bundled-skills/claude-api/shared/tool-use-concepts.md +305 -0
- package/bundled-skills/claude-api/typescript/agent-sdk/README.md +220 -0
- package/bundled-skills/claude-api/typescript/agent-sdk/patterns.md +150 -0
- package/bundled-skills/claude-api/typescript/claude-api/README.md +313 -0
- package/bundled-skills/claude-api/typescript/claude-api/batches.md +106 -0
- package/bundled-skills/claude-api/typescript/claude-api/files-api.md +98 -0
- package/bundled-skills/claude-api/typescript/claude-api/streaming.md +178 -0
- package/bundled-skills/claude-api/typescript/claude-api/tool-use.md +477 -0
- package/bundled-skills/codex-review/SKILL.md +1 -1
- package/bundled-skills/cold-email/SKILL.md +167 -0
- package/bundled-skills/cold-email/evals/evals.json +94 -0
- package/bundled-skills/cold-email/references/benchmarks.md +83 -0
- package/bundled-skills/cold-email/references/follow-up-sequences.md +81 -0
- package/bundled-skills/cold-email/references/frameworks.md +90 -0
- package/bundled-skills/cold-email/references/personalization.md +79 -0
- package/bundled-skills/cold-email/references/subject-lines.md +53 -0
- package/bundled-skills/content-strategy/SKILL.md +374 -0
- package/bundled-skills/content-strategy/evals/evals.json +90 -0
- package/bundled-skills/content-strategy/references/headless-cms.md +194 -0
- package/bundled-skills/context7-auto-research/SKILL.md +1 -1
- package/bundled-skills/dbos-golang/SKILL.md +1 -1
- package/bundled-skills/dbos-python/SKILL.md +1 -1
- package/bundled-skills/dbos-typescript/SKILL.md +1 -1
- package/bundled-skills/debug-buttercup/SKILL.md +1 -1
- package/bundled-skills/defuddle/SKILL.md +50 -0
- package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
- package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
- package/bundled-skills/docs/integrations/jetski-gemini-loader/package.json +1 -0
- package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
- package/bundled-skills/docs/maintainers/skills-import-2026-03-21.md +81 -0
- package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
- package/bundled-skills/docs/users/bundles.md +1 -1
- package/bundled-skills/docs/users/claude-code-skills.md +1 -1
- package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
- package/bundled-skills/docs/users/getting-started.md +1 -1
- package/bundled-skills/docs/users/kiro-integration.md +1 -1
- package/bundled-skills/docs/users/usage.md +4 -4
- package/bundled-skills/docs/users/visual-guide.md +4 -4
- package/bundled-skills/evaluation/SKILL.md +1 -1
- package/bundled-skills/exa-search/SKILL.md +1 -1
- package/bundled-skills/firecrawl-scraper/SKILL.md +1 -1
- package/bundled-skills/frontend-dev-guidelines/SKILL.md +1 -1
- package/bundled-skills/gha-security-review/SKILL.md +2 -1
- package/bundled-skills/git-pushing/SKILL.md +1 -1
- package/bundled-skills/internal-comms/LICENSE.txt +202 -0
- package/bundled-skills/internal-comms/SKILL.md +35 -0
- package/bundled-skills/internal-comms/examples/3p-updates.md +47 -0
- package/bundled-skills/internal-comms/examples/company-newsletter.md +65 -0
- package/bundled-skills/internal-comms/examples/faq-answers.md +30 -0
- package/bundled-skills/internal-comms/examples/general-comms.md +16 -0
- package/bundled-skills/json-canvas/SKILL.md +253 -0
- package/bundled-skills/json-canvas/references/EXAMPLES.md +329 -0
- package/bundled-skills/lead-magnets/SKILL.md +319 -0
- package/bundled-skills/lead-magnets/references/benchmarks.md +129 -0
- package/bundled-skills/lead-magnets/references/format-guide.md +196 -0
- package/bundled-skills/memory-systems/SKILL.md +1 -1
- package/bundled-skills/obsidian-bases/SKILL.md +506 -0
- package/bundled-skills/obsidian-bases/references/FUNCTIONS_REFERENCE.md +173 -0
- package/bundled-skills/obsidian-cli/SKILL.md +115 -0
- package/bundled-skills/obsidian-markdown/SKILL.md +205 -0
- package/bundled-skills/obsidian-markdown/references/CALLOUTS.md +58 -0
- package/bundled-skills/obsidian-markdown/references/EMBEDS.md +63 -0
- package/bundled-skills/obsidian-markdown/references/PROPERTIES.md +61 -0
- package/bundled-skills/product-marketing-context/SKILL.md +250 -0
- package/bundled-skills/product-marketing-context/evals/evals.json +85 -0
- package/bundled-skills/react-best-practices/SKILL.md +1 -1
- package/bundled-skills/revops/SKILL.md +352 -0
- package/bundled-skills/revops/evals/evals.json +91 -0
- package/bundled-skills/revops/references/automation-playbooks.md +290 -0
- package/bundled-skills/revops/references/lifecycle-definitions.md +278 -0
- package/bundled-skills/revops/references/routing-rules.md +203 -0
- package/bundled-skills/revops/references/scoring-models.md +247 -0
- package/bundled-skills/sales-enablement/SKILL.md +358 -0
- package/bundled-skills/sales-enablement/evals/evals.json +91 -0
- package/bundled-skills/sales-enablement/references/deck-frameworks.md +263 -0
- package/bundled-skills/sales-enablement/references/demo-scripts.md +355 -0
- package/bundled-skills/sales-enablement/references/objection-library.md +270 -0
- package/bundled-skills/sales-enablement/references/one-pager-templates.md +208 -0
- package/bundled-skills/seo/SKILL.md +139 -0
- package/bundled-skills/seo/references/cwv-thresholds.md +108 -0
- package/bundled-skills/seo/references/eeat-framework.md +214 -0
- package/bundled-skills/seo/references/quality-gates.md +155 -0
- package/bundled-skills/seo/references/schema-types.md +118 -0
- package/bundled-skills/seo-competitor-pages/SKILL.md +229 -0
- package/bundled-skills/seo-content/SKILL.md +186 -0
- package/bundled-skills/seo-dataforseo/SKILL.md +395 -0
- package/bundled-skills/seo-geo/SKILL.md +254 -0
- package/bundled-skills/seo-hreflang/SKILL.md +209 -0
- package/bundled-skills/seo-image-gen/SKILL.md +183 -0
- package/bundled-skills/seo-images/SKILL.md +193 -0
- package/bundled-skills/seo-page/SKILL.md +103 -0
- package/bundled-skills/seo-plan/SKILL.md +136 -0
- package/bundled-skills/seo-plan/assets/agency.md +175 -0
- package/bundled-skills/seo-plan/assets/ecommerce.md +167 -0
- package/bundled-skills/seo-plan/assets/generic.md +144 -0
- package/bundled-skills/seo-plan/assets/local-service.md +160 -0
- package/bundled-skills/seo-plan/assets/publisher.md +153 -0
- package/bundled-skills/seo-plan/assets/saas.md +135 -0
- package/bundled-skills/seo-programmatic/SKILL.md +184 -0
- package/bundled-skills/seo-schema/SKILL.md +178 -0
- package/bundled-skills/seo-sitemap/SKILL.md +129 -0
- package/bundled-skills/seo-technical/SKILL.md +175 -0
- package/bundled-skills/site-architecture/SKILL.md +366 -0
- package/bundled-skills/site-architecture/evals/evals.json +88 -0
- package/bundled-skills/site-architecture/references/mermaid-templates.md +216 -0
- package/bundled-skills/site-architecture/references/navigation-patterns.md +305 -0
- package/bundled-skills/site-architecture/references/site-type-templates.md +293 -0
- package/bundled-skills/skill-improver/SKILL.md +1 -1
- package/bundled-skills/tavily-web/SKILL.md +1 -1
- package/bundled-skills/test-fixing/SKILL.md +1 -1
- package/bundled-skills/tool-design/SKILL.md +1 -1
- package/bundled-skills/ui-ux-pro-max/SKILL.md +1 -1
- package/bundled-skills/verification-before-completion/SKILL.md +1 -1
- package/bundled-skills/wiki-changelog/SKILL.md +1 -1
- package/bundled-skills/wiki-onboarding/SKILL.md +1 -1
- package/bundled-skills/wiki-qa/SKILL.md +1 -1
- package/bundled-skills/wiki-researcher/SKILL.md +1 -1
- package/bundled-skills/wiki-vitepress/SKILL.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# Tool Use — TypeScript
|
|
2
|
+
|
|
3
|
+
For conceptual overview (tool definitions, tool choice, tips), see [shared/tool-use-concepts.md](../../shared/tool-use-concepts.md).
|
|
4
|
+
|
|
5
|
+
## Tool Runner (Recommended)
|
|
6
|
+
|
|
7
|
+
**Beta:** The tool runner is in beta in the TypeScript SDK.
|
|
8
|
+
|
|
9
|
+
Use `betaZodTool` with Zod schemas to define tools with a `run` function, then pass them to `client.beta.messages.toolRunner()`:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
13
|
+
import { betaZodTool } from "@anthropic-ai/sdk/helpers/beta/zod";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
|
|
16
|
+
const client = new Anthropic();
|
|
17
|
+
|
|
18
|
+
const getWeather = betaZodTool({
|
|
19
|
+
name: "get_weather",
|
|
20
|
+
description: "Get current weather for a location",
|
|
21
|
+
inputSchema: z.object({
|
|
22
|
+
location: z.string().describe("City and state, e.g., San Francisco, CA"),
|
|
23
|
+
unit: z.enum(["celsius", "fahrenheit"]).optional(),
|
|
24
|
+
}),
|
|
25
|
+
run: async (input) => {
|
|
26
|
+
// Your implementation here
|
|
27
|
+
return `72°F and sunny in ${input.location}`;
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// The tool runner handles the agentic loop and returns the final message
|
|
32
|
+
const finalMessage = await client.beta.messages.toolRunner({
|
|
33
|
+
model: "claude-opus-4-6",
|
|
34
|
+
max_tokens: 4096,
|
|
35
|
+
tools: [getWeather],
|
|
36
|
+
messages: [{ role: "user", content: "What's the weather in Paris?" }],
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
console.log(finalMessage.content);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Key benefits of the tool runner:**
|
|
43
|
+
|
|
44
|
+
- No manual loop — the SDK handles calling tools and feeding results back
|
|
45
|
+
- Type-safe tool inputs via Zod schemas
|
|
46
|
+
- Tool schemas are generated automatically from Zod definitions
|
|
47
|
+
- Iteration stops automatically when Claude has no more tool calls
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Manual Agentic Loop
|
|
52
|
+
|
|
53
|
+
Use this when you need fine-grained control (custom logging, conditional tool execution, streaming individual iterations, human-in-the-loop approval):
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
57
|
+
|
|
58
|
+
const client = new Anthropic();
|
|
59
|
+
const tools: Anthropic.Tool[] = [...]; // Your tool definitions
|
|
60
|
+
let messages: Anthropic.MessageParam[] = [{ role: "user", content: userInput }];
|
|
61
|
+
|
|
62
|
+
while (true) {
|
|
63
|
+
const response = await client.messages.create({
|
|
64
|
+
model: "claude-opus-4-6",
|
|
65
|
+
max_tokens: 4096,
|
|
66
|
+
tools: tools,
|
|
67
|
+
messages: messages,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (response.stop_reason === "end_turn") break;
|
|
71
|
+
|
|
72
|
+
// Server-side tool hit iteration limit; re-send to continue
|
|
73
|
+
if (response.stop_reason === "pause_turn") {
|
|
74
|
+
messages = [
|
|
75
|
+
{ role: "user", content: userInput },
|
|
76
|
+
{ role: "assistant", content: response.content },
|
|
77
|
+
];
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const toolUseBlocks = response.content.filter(
|
|
82
|
+
(b): b is Anthropic.ToolUseBlock => b.type === "tool_use",
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
messages.push({ role: "assistant", content: response.content });
|
|
86
|
+
|
|
87
|
+
const toolResults: Anthropic.ToolResultBlockParam[] = [];
|
|
88
|
+
for (const tool of toolUseBlocks) {
|
|
89
|
+
const result = await executeTool(tool.name, tool.input);
|
|
90
|
+
toolResults.push({
|
|
91
|
+
type: "tool_result",
|
|
92
|
+
tool_use_id: tool.id,
|
|
93
|
+
content: result,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
messages.push({ role: "user", content: toolResults });
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Streaming Manual Loop
|
|
102
|
+
|
|
103
|
+
Use `client.messages.stream()` + `finalMessage()` instead of `.create()` when you need streaming within a manual loop. Text deltas are streamed on each iteration; `finalMessage()` collects the complete `Message` so you can inspect `stop_reason` and extract tool-use blocks:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
107
|
+
|
|
108
|
+
const client = new Anthropic();
|
|
109
|
+
const tools: Anthropic.Tool[] = [...];
|
|
110
|
+
let messages: Anthropic.MessageParam[] = [{ role: "user", content: userInput }];
|
|
111
|
+
|
|
112
|
+
while (true) {
|
|
113
|
+
const stream = client.messages.stream({
|
|
114
|
+
model: "claude-opus-4-6",
|
|
115
|
+
max_tokens: 4096,
|
|
116
|
+
tools,
|
|
117
|
+
messages,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Stream text deltas on each iteration
|
|
121
|
+
stream.on("text", (delta) => {
|
|
122
|
+
process.stdout.write(delta);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// finalMessage() resolves with the complete Message — no need to
|
|
126
|
+
// manually wire up .on("message") / .on("error") / .on("abort")
|
|
127
|
+
const message = await stream.finalMessage();
|
|
128
|
+
|
|
129
|
+
if (message.stop_reason === "end_turn") break;
|
|
130
|
+
|
|
131
|
+
// Server-side tool hit iteration limit; re-send to continue
|
|
132
|
+
if (message.stop_reason === "pause_turn") {
|
|
133
|
+
messages = [
|
|
134
|
+
{ role: "user", content: userInput },
|
|
135
|
+
{ role: "assistant", content: message.content },
|
|
136
|
+
];
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const toolUseBlocks = message.content.filter(
|
|
141
|
+
(b): b is Anthropic.ToolUseBlock => b.type === "tool_use",
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
messages.push({ role: "assistant", content: message.content });
|
|
145
|
+
|
|
146
|
+
const toolResults: Anthropic.ToolResultBlockParam[] = [];
|
|
147
|
+
for (const tool of toolUseBlocks) {
|
|
148
|
+
const result = await executeTool(tool.name, tool.input);
|
|
149
|
+
toolResults.push({
|
|
150
|
+
type: "tool_result",
|
|
151
|
+
tool_use_id: tool.id,
|
|
152
|
+
content: result,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
messages.push({ role: "user", content: toolResults });
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
> **Important:** Don't wrap `.on()` events in `new Promise()` to collect the final message — use `stream.finalMessage()` instead. The SDK handles all error/abort/completion states internally.
|
|
161
|
+
|
|
162
|
+
> **Error handling in the loop:** Use the SDK's typed exceptions (e.g., `Anthropic.RateLimitError`, `Anthropic.APIError`) — see [Error Handling](./README.md#error-handling) for examples. Don't check error messages with string matching.
|
|
163
|
+
|
|
164
|
+
> **SDK types:** Use `Anthropic.MessageParam`, `Anthropic.Tool`, `Anthropic.ToolUseBlock`, `Anthropic.ToolResultBlockParam`, `Anthropic.Message`, etc. for all API-related data structures. Don't redefine equivalent interfaces.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Handling Tool Results
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
const response = await client.messages.create({
|
|
172
|
+
model: "claude-opus-4-6",
|
|
173
|
+
max_tokens: 1024,
|
|
174
|
+
tools: tools,
|
|
175
|
+
messages: [{ role: "user", content: "What's the weather in Paris?" }],
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
for (const block of response.content) {
|
|
179
|
+
if (block.type === "tool_use") {
|
|
180
|
+
const result = await executeTool(block.name, block.input);
|
|
181
|
+
|
|
182
|
+
const followup = await client.messages.create({
|
|
183
|
+
model: "claude-opus-4-6",
|
|
184
|
+
max_tokens: 1024,
|
|
185
|
+
tools: tools,
|
|
186
|
+
messages: [
|
|
187
|
+
{ role: "user", content: "What's the weather in Paris?" },
|
|
188
|
+
{ role: "assistant", content: response.content },
|
|
189
|
+
{
|
|
190
|
+
role: "user",
|
|
191
|
+
content: [
|
|
192
|
+
{ type: "tool_result", tool_use_id: block.id, content: result },
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Tool Choice
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const response = await client.messages.create({
|
|
207
|
+
model: "claude-opus-4-6",
|
|
208
|
+
max_tokens: 1024,
|
|
209
|
+
tools: tools,
|
|
210
|
+
tool_choice: { type: "tool", name: "get_weather" },
|
|
211
|
+
messages: [{ role: "user", content: "What's the weather in Paris?" }],
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Code Execution
|
|
218
|
+
|
|
219
|
+
### Basic Usage
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
223
|
+
|
|
224
|
+
const client = new Anthropic();
|
|
225
|
+
|
|
226
|
+
const response = await client.messages.create({
|
|
227
|
+
model: "claude-opus-4-6",
|
|
228
|
+
max_tokens: 4096,
|
|
229
|
+
messages: [
|
|
230
|
+
{
|
|
231
|
+
role: "user",
|
|
232
|
+
content:
|
|
233
|
+
"Calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]",
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
tools: [{ type: "code_execution_20260120", name: "code_execution" }],
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Upload Files for Analysis
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import Anthropic, { toFile } from "@anthropic-ai/sdk";
|
|
244
|
+
import { createReadStream } from "fs";
|
|
245
|
+
|
|
246
|
+
const client = new Anthropic();
|
|
247
|
+
|
|
248
|
+
// 1. Upload a file
|
|
249
|
+
const uploaded = await client.beta.files.upload({
|
|
250
|
+
file: await toFile(createReadStream("sales_data.csv"), undefined, {
|
|
251
|
+
type: "text/csv",
|
|
252
|
+
}),
|
|
253
|
+
betas: ["files-api-2025-04-14"],
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// 2. Pass to code execution
|
|
257
|
+
// Code execution is GA; Files API is still beta (pass via RequestOptions)
|
|
258
|
+
const response = await client.messages.create(
|
|
259
|
+
{
|
|
260
|
+
model: "claude-opus-4-6",
|
|
261
|
+
max_tokens: 4096,
|
|
262
|
+
messages: [
|
|
263
|
+
{
|
|
264
|
+
role: "user",
|
|
265
|
+
content: [
|
|
266
|
+
{
|
|
267
|
+
type: "text",
|
|
268
|
+
text: "Analyze this sales data. Show trends and create a visualization.",
|
|
269
|
+
},
|
|
270
|
+
{ type: "container_upload", file_id: uploaded.id },
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
tools: [{ type: "code_execution_20260120", name: "code_execution" }],
|
|
275
|
+
},
|
|
276
|
+
{ headers: { "anthropic-beta": "files-api-2025-04-14" } },
|
|
277
|
+
);
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Retrieve Generated Files
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
import path from "path";
|
|
284
|
+
import fs from "fs";
|
|
285
|
+
|
|
286
|
+
const OUTPUT_DIR = "./claude_outputs";
|
|
287
|
+
await fs.promises.mkdir(OUTPUT_DIR, { recursive: true });
|
|
288
|
+
|
|
289
|
+
for (const block of response.content) {
|
|
290
|
+
if (block.type === "bash_code_execution_tool_result") {
|
|
291
|
+
const result = block.content;
|
|
292
|
+
if (result.type === "bash_code_execution_result" && result.content) {
|
|
293
|
+
for (const fileRef of result.content) {
|
|
294
|
+
if (fileRef.type === "bash_code_execution_output") {
|
|
295
|
+
const metadata = await client.beta.files.retrieveMetadata(
|
|
296
|
+
fileRef.file_id,
|
|
297
|
+
);
|
|
298
|
+
const response = await client.beta.files.download(fileRef.file_id);
|
|
299
|
+
const fileBytes = Buffer.from(await response.arrayBuffer());
|
|
300
|
+
const safeName = path.basename(metadata.filename);
|
|
301
|
+
if (!safeName || safeName === "." || safeName === "..") {
|
|
302
|
+
console.warn(`Skipping invalid filename: ${metadata.filename}`);
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
const outputPath = path.join(OUTPUT_DIR, safeName);
|
|
306
|
+
await fs.promises.writeFile(outputPath, fileBytes);
|
|
307
|
+
console.log(`Saved: ${outputPath}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Container Reuse
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
// First request: set up environment
|
|
319
|
+
const response1 = await client.messages.create({
|
|
320
|
+
model: "claude-opus-4-6",
|
|
321
|
+
max_tokens: 4096,
|
|
322
|
+
messages: [
|
|
323
|
+
{
|
|
324
|
+
role: "user",
|
|
325
|
+
content: "Install tabulate and create data.json with sample user data",
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
tools: [{ type: "code_execution_20260120", name: "code_execution" }],
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// Reuse container
|
|
332
|
+
const containerId = response1.container.id;
|
|
333
|
+
|
|
334
|
+
const response2 = await client.messages.create({
|
|
335
|
+
container: containerId,
|
|
336
|
+
model: "claude-opus-4-6",
|
|
337
|
+
max_tokens: 4096,
|
|
338
|
+
messages: [
|
|
339
|
+
{
|
|
340
|
+
role: "user",
|
|
341
|
+
content: "Read data.json and display as a formatted table",
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
tools: [{ type: "code_execution_20260120", name: "code_execution" }],
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Memory Tool
|
|
351
|
+
|
|
352
|
+
### Basic Usage
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
const response = await client.messages.create({
|
|
356
|
+
model: "claude-opus-4-6",
|
|
357
|
+
max_tokens: 2048,
|
|
358
|
+
messages: [
|
|
359
|
+
{
|
|
360
|
+
role: "user",
|
|
361
|
+
content: "Remember that my preferred language is TypeScript.",
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
tools: [{ type: "memory_20250818", name: "memory" }],
|
|
365
|
+
});
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### SDK Memory Helper
|
|
369
|
+
|
|
370
|
+
Use `betaMemoryTool` with a `MemoryToolHandlers` implementation:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
import {
|
|
374
|
+
betaMemoryTool,
|
|
375
|
+
type MemoryToolHandlers,
|
|
376
|
+
} from "@anthropic-ai/sdk/helpers/beta/memory";
|
|
377
|
+
|
|
378
|
+
const handlers: MemoryToolHandlers = {
|
|
379
|
+
async view(command) { ... },
|
|
380
|
+
async create(command) { ... },
|
|
381
|
+
async str_replace(command) { ... },
|
|
382
|
+
async insert(command) { ... },
|
|
383
|
+
async delete(command) { ... },
|
|
384
|
+
async rename(command) { ... },
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const memory = betaMemoryTool(handlers);
|
|
388
|
+
|
|
389
|
+
const runner = client.beta.messages.toolRunner({
|
|
390
|
+
model: "claude-opus-4-6",
|
|
391
|
+
max_tokens: 2048,
|
|
392
|
+
tools: [memory],
|
|
393
|
+
messages: [{ role: "user", content: "Remember my preferences" }],
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
for await (const message of runner) {
|
|
397
|
+
console.log(message);
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
For full implementation examples, use WebFetch:
|
|
402
|
+
|
|
403
|
+
- `https://github.com/anthropics/anthropic-sdk-typescript/blob/main/examples/tools-helpers-memory.ts`
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Structured Outputs
|
|
408
|
+
|
|
409
|
+
### JSON Outputs (Zod — Recommended)
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
413
|
+
import { z } from "zod";
|
|
414
|
+
import { zodOutputFormat } from "@anthropic-ai/sdk/helpers/zod";
|
|
415
|
+
|
|
416
|
+
const ContactInfoSchema = z.object({
|
|
417
|
+
name: z.string(),
|
|
418
|
+
email: z.string(),
|
|
419
|
+
plan: z.string(),
|
|
420
|
+
interests: z.array(z.string()),
|
|
421
|
+
demo_requested: z.boolean(),
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
const client = new Anthropic();
|
|
425
|
+
|
|
426
|
+
const response = await client.messages.parse({
|
|
427
|
+
model: "claude-opus-4-6",
|
|
428
|
+
max_tokens: 1024,
|
|
429
|
+
messages: [
|
|
430
|
+
{
|
|
431
|
+
role: "user",
|
|
432
|
+
content:
|
|
433
|
+
"Extract: Jane Doe (jane@co.com) wants Enterprise, interested in API and SDKs, wants a demo.",
|
|
434
|
+
},
|
|
435
|
+
],
|
|
436
|
+
output_config: {
|
|
437
|
+
format: zodOutputFormat(ContactInfoSchema),
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
console.log(response.parsed_output.name); // "Jane Doe"
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Strict Tool Use
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
const response = await client.messages.create({
|
|
448
|
+
model: "claude-opus-4-6",
|
|
449
|
+
max_tokens: 1024,
|
|
450
|
+
messages: [
|
|
451
|
+
{
|
|
452
|
+
role: "user",
|
|
453
|
+
content: "Book a flight to Tokyo for 2 passengers on March 15",
|
|
454
|
+
},
|
|
455
|
+
],
|
|
456
|
+
tools: [
|
|
457
|
+
{
|
|
458
|
+
name: "book_flight",
|
|
459
|
+
description: "Book a flight to a destination",
|
|
460
|
+
strict: true,
|
|
461
|
+
input_schema: {
|
|
462
|
+
type: "object",
|
|
463
|
+
properties: {
|
|
464
|
+
destination: { type: "string" },
|
|
465
|
+
date: { type: "string", format: "date" },
|
|
466
|
+
passengers: {
|
|
467
|
+
type: "integer",
|
|
468
|
+
enum: [1, 2, 3, 4, 5, 6, 7, 8],
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
required: ["destination", "date", "passengers"],
|
|
472
|
+
additionalProperties: false,
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
],
|
|
476
|
+
});
|
|
477
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: codex-review
|
|
3
|
-
description: "Professional code review with auto CHANGELOG generation, integrated with Codex AI"
|
|
3
|
+
description: "Professional code review with auto CHANGELOG generation, integrated with Codex AI. Use when you want professional code review before commits, you need automatic CHANGELOG generation, or reviewing large-scale refactoring."
|
|
4
4
|
risk: unknown
|
|
5
5
|
source: community
|
|
6
6
|
date_added: "2026-02-27"
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cold-email
|
|
3
|
+
description: "Write B2B cold emails and follow-up sequences that earn replies. Use when creating outbound prospecting emails, SDR outreach, personalized opening lines, subject lines, CTAs, and multi-touch follow-up sequences."
|
|
4
|
+
risk: unknown
|
|
5
|
+
source: "https://github.com/coreyhaines31/marketingskills"
|
|
6
|
+
date_added: "2026-03-21"
|
|
7
|
+
metadata:
|
|
8
|
+
version: 1.1.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Cold Email Writing
|
|
12
|
+
|
|
13
|
+
You are an expert cold email writer. Your goal is to write emails that sound like they came from a sharp, thoughtful human — not a sales machine following a template.
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- Use when writing outbound prospecting emails or cold follow-up sequences.
|
|
18
|
+
- Use when the task is getting replies from people with no existing relationship.
|
|
19
|
+
- Use when the user wants sharper subject lines, openings, CTAs, or personalization.
|
|
20
|
+
|
|
21
|
+
## Before Writing
|
|
22
|
+
|
|
23
|
+
**Check for product marketing context first:**
|
|
24
|
+
If `.agents/product-marketing-context.md` exists (or `.claude/product-marketing-context.md` in older setups), read it before asking questions. Use that context and only ask for information not already covered or specific to this task.
|
|
25
|
+
|
|
26
|
+
Understand the situation (ask if not provided):
|
|
27
|
+
|
|
28
|
+
1. **Who are you writing to?** — Role, company, why them specifically
|
|
29
|
+
2. **What do you want?** — The outcome (meeting, reply, intro, demo)
|
|
30
|
+
3. **What's the value?** — The specific problem you solve for people like them
|
|
31
|
+
4. **What's your proof?** — A result, case study, or credibility signal
|
|
32
|
+
5. **Any research signals?** — Funding, hiring, LinkedIn posts, company news, tech stack changes
|
|
33
|
+
|
|
34
|
+
Work with whatever the user gives you. If they have a strong signal and a clear value prop, that's enough to write. Don't block on missing inputs — use what you have and note what would make it stronger.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Writing Principles
|
|
39
|
+
|
|
40
|
+
### Write like a peer, not a vendor
|
|
41
|
+
|
|
42
|
+
The email should read like it came from someone who understands their world — not someone trying to sell them something. Use contractions. Read it aloud. If it sounds like marketing copy, rewrite it.
|
|
43
|
+
|
|
44
|
+
### Every sentence must earn its place
|
|
45
|
+
|
|
46
|
+
Cold email is ruthlessly short. If a sentence doesn't move the reader toward replying, cut it. The best cold emails feel like they could have been shorter, not longer.
|
|
47
|
+
|
|
48
|
+
### Personalization must connect to the problem
|
|
49
|
+
|
|
50
|
+
If you remove the personalized opening and the email still makes sense, the personalization isn't working. The observation should naturally lead into why you're reaching out.
|
|
51
|
+
|
|
52
|
+
See [personalization.md](references/personalization.md) for the 4-level system and research signals.
|
|
53
|
+
|
|
54
|
+
### Lead with their world, not yours
|
|
55
|
+
|
|
56
|
+
The reader should see their own situation reflected back. "You/your" should dominate over "I/we." Don't open with who you are or what your company does.
|
|
57
|
+
|
|
58
|
+
### One ask, low friction
|
|
59
|
+
|
|
60
|
+
Interest-based CTAs ("Worth exploring?" / "Would this be useful?") beat meeting requests. One CTA per email. Make it easy to say yes with a one-line reply.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Voice & Tone
|
|
65
|
+
|
|
66
|
+
**The target voice:** A smart colleague who noticed something relevant and is sharing it. Conversational but not sloppy. Confident but not pushy.
|
|
67
|
+
|
|
68
|
+
**Calibrate to the audience:**
|
|
69
|
+
|
|
70
|
+
- C-suite: ultra-brief, peer-level, understated
|
|
71
|
+
- Mid-level: more specific value, slightly more detail
|
|
72
|
+
- Technical: precise, no fluff, respect their intelligence
|
|
73
|
+
|
|
74
|
+
**What it should NOT sound like:**
|
|
75
|
+
|
|
76
|
+
- A template with fields swapped in
|
|
77
|
+
- A pitch deck compressed into paragraph form
|
|
78
|
+
- A LinkedIn DM from someone you've never met
|
|
79
|
+
- An AI-generated email (avoid the telltale patterns: "I hope this email finds you well," "I came across your profile," "leverage," "synergy," "best-in-class")
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Structure
|
|
84
|
+
|
|
85
|
+
There's no single right structure. Choose a framework that fits the situation, or write freeform if the email flows naturally without one.
|
|
86
|
+
|
|
87
|
+
**Common shapes that work:**
|
|
88
|
+
|
|
89
|
+
- **Observation → Problem → Proof → Ask** — You noticed X, which usually means Y challenge. We helped Z with that. Interested?
|
|
90
|
+
- **Question → Value → Ask** — Struggling with X? We do Y. Company Z saw [result]. Worth a look?
|
|
91
|
+
- **Trigger → Insight → Ask** — Congrats on X. That usually creates Y challenge. We've helped similar companies with that. Curious?
|
|
92
|
+
- **Story → Bridge → Ask** — [Similar company] had [problem]. They [solved it this way]. Relevant to you?
|
|
93
|
+
|
|
94
|
+
For the full catalog of frameworks with examples, see [frameworks.md](references/frameworks.md).
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Subject Lines
|
|
99
|
+
|
|
100
|
+
Short, boring, internal-looking. The subject line's only job is to get the email opened — not to sell.
|
|
101
|
+
|
|
102
|
+
- 2-4 words, lowercase, no punctuation tricks
|
|
103
|
+
- Should look like it came from a colleague ("reply rates," "hiring ops," "Q2 forecast")
|
|
104
|
+
- No product pitches, no urgency, no emojis, no prospect's first name
|
|
105
|
+
|
|
106
|
+
See [subject-lines.md](references/subject-lines.md) for the full data.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Follow-Up Sequences
|
|
111
|
+
|
|
112
|
+
Each follow-up should add something new — a different angle, fresh proof, a useful resource. "Just checking in" gives the reader no reason to respond.
|
|
113
|
+
|
|
114
|
+
- 3-5 total emails, increasing gaps between them
|
|
115
|
+
- Each email should stand alone (they may not have read the previous ones)
|
|
116
|
+
- The breakup email is your last touch — honor it
|
|
117
|
+
|
|
118
|
+
See [follow-up-sequences.md](references/follow-up-sequences.md) for cadence, angle rotation, and breakup email templates.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Quality Check
|
|
123
|
+
|
|
124
|
+
Before presenting, gut-check:
|
|
125
|
+
|
|
126
|
+
- Does it sound like a human wrote it? (Read it aloud)
|
|
127
|
+
- Would YOU reply to this if you received it?
|
|
128
|
+
- Does every sentence serve the reader, not the sender?
|
|
129
|
+
- Is the personalization connected to the problem?
|
|
130
|
+
- Is there one clear, low-friction ask?
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## What to Avoid
|
|
135
|
+
|
|
136
|
+
- Opening with "I hope this email finds you well" or "My name is X and I work at Y"
|
|
137
|
+
- Jargon: "synergy," "leverage," "circle back," "best-in-class," "leading provider"
|
|
138
|
+
- Feature dumps — one proof point beats ten features
|
|
139
|
+
- HTML, images, or multiple links
|
|
140
|
+
- Fake "Re:" or "Fwd:" subject lines
|
|
141
|
+
- Identical templates with only {{FirstName}} swapped
|
|
142
|
+
- Asking for 30-minute calls in first touch
|
|
143
|
+
- "Just checking in" follow-ups
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Data & Benchmarks
|
|
148
|
+
|
|
149
|
+
The references contain performance data if you need to make informed choices:
|
|
150
|
+
|
|
151
|
+
- [benchmarks.md](references/benchmarks.md) — Reply rates, conversion funnels, expert methods, common mistakes
|
|
152
|
+
- [personalization.md](references/personalization.md) — 4-level personalization system, research signals
|
|
153
|
+
- [subject-lines.md](references/subject-lines.md) — Subject line data and optimization
|
|
154
|
+
- [follow-up-sequences.md](references/follow-up-sequences.md) — Cadence, angles, breakup emails
|
|
155
|
+
- [frameworks.md](references/frameworks.md) — All copywriting frameworks with examples
|
|
156
|
+
|
|
157
|
+
Use this data to inform your writing — not as a checklist to satisfy.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Related Skills
|
|
162
|
+
|
|
163
|
+
- **copywriting**: For landing pages and web copy
|
|
164
|
+
- **email-sequence**: For lifecycle/nurture email sequences (not cold outreach)
|
|
165
|
+
- **social-content**: For LinkedIn and social posts
|
|
166
|
+
- **product-marketing-context**: For establishing foundational positioning
|
|
167
|
+
- **revops**: For lead scoring, routing, and pipeline management
|