@kjerneverk/execution-anthropic 1.0.4-dev.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.
Files changed (42) hide show
  1. package/.kodrdriv-test-cache.json +6 -0
  2. package/LICENSE +18 -0
  3. package/README.md +83 -0
  4. package/dist/index.d.ts +85 -0
  5. package/dist/index.js +123 -0
  6. package/dist/index.js.map +1 -0
  7. package/output/kodrdriv/.kodrdriv-parallel-context.json +584 -0
  8. package/output/kodrdriv/.kodrdriv-parallel-context.json.lock +2 -0
  9. package/output/kodrdriv/260110-1741-release-notes.md +36 -0
  10. package/output/kodrdriv/260112-2201-commit-message.md +1 -0
  11. package/output/kodrdriv/260112-2202-release-notes.md +39 -0
  12. package/output/kodrdriv/260112-2340-commit-message.md +1 -0
  13. package/output/kodrdriv/260113-0022-commit-message.md +1 -0
  14. package/output/kodrdriv/260113-0023-release-notes.md +45 -0
  15. package/output/kodrdriv/260114-0655-commit-message.md +5 -0
  16. package/output/kodrdriv/260115-0616-commit-message.md +4 -0
  17. package/output/kodrdriv/260115-0739-commit-message.md +1 -0
  18. package/output/kodrdriv/260126-0919-commit-message.md +1 -0
  19. package/output/kodrdriv/260126-0921-release-notes.md +34 -0
  20. package/output/kodrdriv/260128-0923-commit-message.md +3 -0
  21. package/output/kodrdriv/260128-0924-release-notes.md +23 -0
  22. package/output/kodrdriv/260130-1638-commit-message.md +1 -0
  23. package/output/kodrdriv/260130-1645-commit-message.md +1 -0
  24. package/output/kodrdriv/260130-1646-release-notes.md +30 -0
  25. package/output/kodrdriv/RELEASE_NOTES.md +28 -0
  26. package/output/kodrdriv/RELEASE_TITLE.md +1 -0
  27. package/output/kodrdriv/agentic-reflection-commit-2026-01-13T06-01-28-797Z.md +97 -0
  28. package/output/kodrdriv/agentic-reflection-commit-2026-01-13T07-40-49-371Z.md +97 -0
  29. package/output/kodrdriv/agentic-reflection-commit-2026-01-13T08-22-38-911Z.md +97 -0
  30. package/output/kodrdriv/agentic-reflection-commit-2026-01-14T14-55-30-939Z.md +118 -0
  31. package/output/kodrdriv/agentic-reflection-commit-2026-01-15T14-16-26-349Z.md +117 -0
  32. package/output/kodrdriv/agentic-reflection-commit-2026-01-15T15-39-45-943Z.md +97 -0
  33. package/output/kodrdriv/agentic-reflection-commit-2026-01-26T17-19-48-407Z.md +188 -0
  34. package/output/kodrdriv/agentic-reflection-commit-2026-01-31T00-38-51-441Z.md +160 -0
  35. package/output/kodrdriv/agentic-reflection-commit-2026-01-31T00-45-53-143Z.md +130 -0
  36. package/output/kodrdriv/agentic-reflection-release-2026-01-11T01-41-03-039Z.md +330 -0
  37. package/output/kodrdriv/agentic-reflection-release-2026-01-13T06-02-11-920Z.md +270 -0
  38. package/output/kodrdriv/agentic-reflection-release-2026-01-13T08-23-08-625Z.md +299 -0
  39. package/output/kodrdriv/agentic-reflection-release-2026-01-26T17-21-17-390Z.md +365 -0
  40. package/output/kodrdriv/agentic-reflection-release-2026-01-31T00-46-16-542Z.md +362 -0
  41. package/package.json +57 -0
  42. package/package.json~ +56 -0
@@ -0,0 +1,362 @@
1
+ # Agentic Workflow - Self-Reflection Report
2
+
3
+ Generated: 2026-01-31T00:46:16.543Z
4
+
5
+ ## Execution Summary
6
+
7
+ - **Iterations**: 9
8
+ - **Tool Calls**: 14
9
+ - **Unique Tools**: 11
10
+
11
+ ## Tool Effectiveness Analysis
12
+
13
+ | Tool | Calls | Success | Failures | Success Rate | Avg Duration |
14
+ |------|-------|---------|----------|--------------|--------------|
15
+ | get_file_content | 4 | 4 | 0 | 100.0% | 0ms |
16
+ | get_release_stats | 1 | 1 | 0 | 100.0% | 50ms |
17
+ | get_tag_history | 1 | 1 | 0 | 100.0% | 55ms |
18
+ | analyze_commit_patterns | 1 | 1 | 0 | 100.0% | 7ms |
19
+ | get_breaking_changes | 1 | 1 | 0 | 100.0% | 21ms |
20
+ | compare_previous_release | 1 | 1 | 0 | 100.0% | 43ms |
21
+ | group_files_by_concern | 1 | 1 | 0 | 100.0% | 1ms |
22
+ | search_codebase | 1 | 1 | 0 | 100.0% | 11ms |
23
+ | get_file_dependencies | 1 | 1 | 0 | 100.0% | 47ms |
24
+ | get_related_tests | 1 | 1 | 0 | 100.0% | 1ms |
25
+ | get_file_history | 1 | 1 | 0 | 100.0% | 10ms |
26
+
27
+ ### Tool Performance Insights
28
+
29
+ **Most Frequently Used:**
30
+ - get_release_stats: 1 calls
31
+ - get_tag_history: 1 calls
32
+ - analyze_commit_patterns: 1 calls
33
+
34
+ ## Recommendations for Improvement
35
+
36
+ - **Underutilized Tools**: Many tools were called only once. Consider whether all tools are necessary or if the agent needs better guidance on when to use them.
37
+
38
+ ## Detailed Execution Timeline
39
+
40
+ | Time | Iteration | Tool | Result | Duration |
41
+ |------|-----------|------|--------|----------|
42
+ | 4:45:56 PM | 1 | get_release_stats | ✅ Success | 50ms |
43
+ | 4:45:56 PM | 1 | get_tag_history | ✅ Success | 55ms |
44
+ | 4:45:56 PM | 1 | analyze_commit_patterns | ✅ Success | 7ms |
45
+ | 4:45:56 PM | 1 | get_breaking_changes | ✅ Success | 21ms |
46
+ | 4:45:57 PM | 2 | compare_previous_release | ✅ Success | 43ms |
47
+ | 4:45:58 PM | 3 | group_files_by_concern | ✅ Success | 1ms |
48
+ | 4:45:59 PM | 4 | get_file_content | ✅ Success | 0ms |
49
+ | 4:45:59 PM | 4 | get_file_content | ✅ Success | 0ms |
50
+ | 4:46:00 PM | 4 | get_file_content | ✅ Success | 1ms |
51
+ | 4:46:01 PM | 5 | search_codebase | ✅ Success | 11ms |
52
+ | 4:46:03 PM | 6 | get_file_dependencies | ✅ Success | 47ms |
53
+ | 4:46:03 PM | 6 | get_related_tests | ✅ Success | 1ms |
54
+ | 4:46:03 PM | 7 | get_file_content | ✅ Success | 0ms |
55
+ | 4:46:04 PM | 8 | get_file_history | ✅ Success | 10ms |
56
+
57
+ ## Conversation History
58
+
59
+ <details>
60
+ <summary>Click to expand full agentic interaction</summary>
61
+
62
+ ```json
63
+ [
64
+ {
65
+ "role": "system",
66
+ "content": "You are a professional software engineer writing release notes for your team and users.\n\n## Available Tools\n\nYou have access to tools to investigate the release:\n- `get_tag_history` - Understand release patterns\n- `get_release_stats` - Quantify scope of changes\n- `compare_previous_release` - See how this compares to previous releases\n- `group_files_by_concern` - Identify themes in changes\n- `analyze_commit_patterns` - Detect patterns in commits\n- `get_file_content` - Read file contents or diffs\n- `analyze_diff_section` - Expand unclear changes\n- `get_file_history` - Understand how code evolved\n- `get_file_dependencies` - Assess impact and reach\n- `search_codebase` - Find usage patterns\n- `get_related_tests` - Understand behavior changes\n- `get_breaking_changes` - Identify breaking changes (always use this)\n\nUse these tools to investigate the changes rather than asking for information upfront.\n\n## Your Task\n\nWrite release notes that clearly explain what's in this release and why it matters. Your notes should help users and developers understand what changed without needing to read every commit.\n\nFocus on:\n- What problems does this release solve?\n- What new capabilities does it add?\n- What's the impact on users and developers?\n- Are there breaking changes or important considerations?\n\nUse the available tools to investigate the changes. The more you understand, the better your notes will be.\n\n**Important**: If additional context is provided (from context files or other sources), use your judgment:\n- If the context is relevant to this specific package/release, incorporate it appropriately\n- If the context describes changes in other packages or unrelated work, ignore it\n- Don't fabricate connections between this package and unrelated context\n- Be honest about what changed - only mention what actually happened in this release\n- Context is supplemental information, not a requirement to include\n\n## Investigation Approach\n\nUse tools based on what you need to know:\n\n**Context:**\n- get_tag_history - understand release patterns\n- get_release_stats - quantify scope\n- compare_previous_release - see how this compares\n\n**Understanding:**\n- group_files_by_concern - identify themes\n- analyze_commit_patterns - detect patterns\n- get_file_content - see full context\n- analyze_diff_section - expand unclear changes\n- get_file_history - understand evolution\n\n**Impact:**\n- get_file_dependencies - assess reach\n- search_codebase - find usage patterns\n- get_related_tests - understand behavior changes\n- get_breaking_changes - identify breaking changes (always use)\n\n## Writing Style\n\nWrite naturally and directly:\n- Use plain language that users can understand\n- Be specific about what changed and why\n- Avoid marketing speak and buzzwords\n- No emojis or excessive punctuation\n- No phrases like \"we're excited to announce\"\n- No meta-commentary about the release itself\n- Focus on facts and implications, not enthusiasm\n\nStructure your notes logically:\n- Start with the most important changes\n- Group related changes together\n- Explain breaking changes clearly\n- Include practical examples when helpful\n\n## Output Format\n\nWhen ready, output your release notes in this exact format:\n\nRELEASE_TITLE:\n[A clear, factual title describing the main changes]\n\nRELEASE_BODY:\n[Detailed release notes in Markdown format]\n\nDo not include any JSON, code blocks, or wrapper syntax. Output plain text and markdown only.\nNo conversational remarks or follow-up offers."
67
+ },
68
+ {
69
+ "role": "user",
70
+ "content": "I need comprehensive release notes for changes from main to HEAD.\n\n**CRITICAL VERSION INSTRUCTION: This is a release for version 1.0.3. You MUST use EXACTLY \"1.0.3\" in your release title. DO NOT use any development/prerelease version numbers you may see in the diff (like 1.0.3-dev.0 or similar). The release version is 1.0.3.**\n\n## Your Analysis Task\n\nUse your tools to investigate the changes between main and HEAD:\n1. Use `get_release_stats` to understand the scope of changes\n2. Use `get_tag_history` or `compare_previous_release` to see release patterns\n3. Use `analyze_commit_patterns` to detect themes\n4. Use `group_files_by_concern` to identify logical groupings\n5. Use `get_breaking_changes` to identify breaking changes (always check this)\n6. Use `get_file_content` or `analyze_diff_section` to understand specific changes\n7. Use `get_file_dependencies` and `search_codebase` to assess impact\n\nWrite clear release notes that answer:\n- What's the main story of this release?\n- What problems does it solve?\n- What's the impact on users and developers?\n- Are there breaking changes?\n\nIf context information is provided, use it only if relevant to this specific package.\nDon't force connections that don't exist - if context describes changes in other packages\nor unrelated features, simply ignore it and focus on what actually changed in this release.\n\nStart by gathering statistics and understanding the scope, then investigate specific changes as needed."
71
+ },
72
+ {
73
+ "role": "assistant",
74
+ "content": null,
75
+ "tool_calls": [
76
+ {
77
+ "id": "call_j1c1jF1YkcN8qLHm9VKDUE7q",
78
+ "type": "function",
79
+ "function": {
80
+ "name": "get_release_stats",
81
+ "arguments": "{\"fromRef\": \"main\", \"toRef\": \"HEAD\"}"
82
+ }
83
+ },
84
+ {
85
+ "id": "call_EiVre0igfADZxfAEMJPOOr66",
86
+ "type": "function",
87
+ "function": {
88
+ "name": "get_tag_history",
89
+ "arguments": "{\"limit\": 10, \"pattern\": \"v*\"}"
90
+ }
91
+ },
92
+ {
93
+ "id": "call_MTmR8oy0Y7gtc1jutFhXyW8B",
94
+ "type": "function",
95
+ "function": {
96
+ "name": "analyze_commit_patterns",
97
+ "arguments": "{\"fromRef\": \"main\", \"toRef\": \"HEAD\"}"
98
+ }
99
+ },
100
+ {
101
+ "id": "call_8jc6TS4pLyQMx64twUMf72yY",
102
+ "type": "function",
103
+ "function": {
104
+ "name": "get_breaking_changes",
105
+ "arguments": "{\"fromRef\": \"main\", \"toRef\": \"HEAD\"}"
106
+ }
107
+ }
108
+ ]
109
+ },
110
+ {
111
+ "role": "tool",
112
+ "tool_call_id": "call_j1c1jF1YkcN8qLHm9VKDUE7q",
113
+ "content": "Total commits: 5\n\nContributors:\n 5\tTim O'Brien\n\n\nFile changes: 3 files changed, 7 insertions(+), 7 deletions(-)\n\nTop 10 most changed files:\n vite.config.ts | 4 ++--\n src/index.ts | 4 ++--\n package.json | 6 +++---\n 3 files changed, 7 insertions(+), 7 deletions(-)\n",
114
+ "name": "get_release_stats"
115
+ },
116
+ {
117
+ "role": "tool",
118
+ "tool_call_id": "call_EiVre0igfADZxfAEMJPOOr66",
119
+ "content": "Recent release tags:\nv1.0.1: 2026-01-28 09:24:53 -0800 - fix: add npm tag detection for prerelease versions in publish workflow (#14)\nv1.0.0: 2026-01-26 09:21:23 -0800 - chore(release): bump package version to 1.0.0 (#13)\nv0.0.4: 2026-01-13 00:23:46 -0800 - chore(release): bump @riotprompt/execution-anthropic to 0.0.4 (#7)\nv0.0.3: 2026-01-12 22:03:01 -0800 - chore(release): bump @riotprompt/execution-anthropic to 0.0.3 (#6)\nv0.0.3-dev.0: tag v0.0.3-dev.0\nTagger: Tim O'Brien <tobrien@discursive.com>\n\n0.0.3-dev.0\n2026-01-10 17:45:38 -0800 - 0.0.3-dev.0\nv0.0.2: 2026-01-10 17:41:07 -0800 - Updated and separated tests (#5)\nv0.0.2-dev.0: tag v0.0.2-dev.0\nTagger: Tim O'Brien <tobrien@discursive.com>\n\n0.0.2-dev.0\n2026-01-10 11:23:15 -0800 - 0.0.2-dev.0",
120
+ "name": "get_tag_history"
121
+ },
122
+ {
123
+ "role": "tool",
124
+ "tool_call_id": "call_MTmR8oy0Y7gtc1jutFhXyW8B",
125
+ "content": "Commit types:\n chore: 3\n feat: 1\n\nTop keywords in commits:\n chore: 3\n release: 1\n package: 1\n version: 1\n harden: 1\n anthropic: 1\n provider: 1\n redaction: 1\n sanitized: 1\n errors: 1\n merge: 1\n working: 1",
126
+ "name": "analyze_commit_patterns"
127
+ },
128
+ {
129
+ "role": "tool",
130
+ "tool_call_id": "call_8jc6TS4pLyQMx64twUMf72yY",
131
+ "content": "No obvious breaking changes detected. Manual review recommended for API changes.",
132
+ "name": "get_breaking_changes"
133
+ },
134
+ {
135
+ "role": "assistant",
136
+ "content": null,
137
+ "tool_calls": [
138
+ {
139
+ "id": "call_3ExCPNzItrPgFFO4biszpBDw",
140
+ "type": "function",
141
+ "function": {
142
+ "name": "compare_previous_release",
143
+ "arguments": "{\"previousTag\":\"v1.0.1\",\"currentRef\":\"HEAD\",\"statsOnly\":false}"
144
+ }
145
+ }
146
+ ]
147
+ },
148
+ {
149
+ "role": "tool",
150
+ "tool_call_id": "call_3ExCPNzItrPgFFO4biszpBDw",
151
+ "content": "Comparison between v1.0.1 and HEAD:\n\nCommits: 6\n\nFile changes:\n package.json | 6 +++---\n src/index.ts | 4 ++--\n vite.config.ts | 4 ++--\n 3 files changed, 7 insertions(+), 7 deletions(-)\n\n\nCommit summary:\n7e648da chore(release): bump package version to 1.0.3\n5dd4963 feat: harden Anthropic provider with API key redaction + sanitized errors\n0464de8 chore: bump to 1.0.3-dev.0\n1d1e2de Merge main into working for sync\ndd23b69 chore: bump to 1.0.2-dev.0 (#15)\n344f20e chore: bump to 1.0.2-dev.0\n",
152
+ "name": "compare_previous_release"
153
+ },
154
+ {
155
+ "role": "assistant",
156
+ "content": null,
157
+ "tool_calls": [
158
+ {
159
+ "id": "call_RgHhpq85rtw9AlyWhUupelEN",
160
+ "type": "function",
161
+ "function": {
162
+ "name": "group_files_by_concern",
163
+ "arguments": "{\"filePaths\":[\"vite.config.ts\",\"src/index.ts\",\"package.json\"]}"
164
+ }
165
+ }
166
+ ]
167
+ },
168
+ {
169
+ "role": "tool",
170
+ "tool_call_id": "call_RgHhpq85rtw9AlyWhUupelEN",
171
+ "content": "other (1 files):\n - vite.config.ts\n\nsource:src (1 files):\n - src/index.ts\n\ndependencies (1 files):\n - package.json\n\nSuggestion: These 3 groups represent different concerns in the release.",
172
+ "name": "group_files_by_concern"
173
+ },
174
+ {
175
+ "role": "assistant",
176
+ "content": null,
177
+ "tool_calls": [
178
+ {
179
+ "id": "call_GglyFWZKhUJyaRhs2p0HHCLD",
180
+ "type": "function",
181
+ "function": {
182
+ "name": "get_file_content",
183
+ "arguments": "{\"filePath\": \"src/index.ts\", \"includeLineNumbers\": true}"
184
+ }
185
+ },
186
+ {
187
+ "id": "call_iSqtllNZxaTkIRj5nrpzqsNY",
188
+ "type": "function",
189
+ "function": {
190
+ "name": "get_file_content",
191
+ "arguments": "{\"filePath\": \"package.json\", \"includeLineNumbers\": true}"
192
+ }
193
+ },
194
+ {
195
+ "id": "call_vV6it6Rx8gLxiESCOEKBqzAV",
196
+ "type": "function",
197
+ "function": {
198
+ "name": "get_file_content",
199
+ "arguments": "{\"filePath\": \"vite.config.ts\", \"includeLineNumbers\": true}"
200
+ }
201
+ }
202
+ ]
203
+ },
204
+ {
205
+ "role": "tool",
206
+ "tool_call_id": "call_GglyFWZKhUJyaRhs2p0HHCLD",
207
+ "content": "1: /**\n2: * Execution Anthropic Package\n3: *\n4: * Anthropic provider implementation for LLM execution.\n5: *\n6: * @packageDocumentation\n7: */\n8: \n9: import Anthropic from '@anthropic-ai/sdk';\n10: import { getRedactor } from '@utilarium/offrecord';\n11: import { \n12: createSafeError, \n13: configureErrorSanitizer,\n14: configureSecretGuard,\n15: } from '@utilarium/spotclean';\n16: \n17: // Register Anthropic API key patterns on module load\n18: const redactor = getRedactor();\n19: redactor.register({\n20: name: 'anthropic',\n21: patterns: [\n22: /sk-ant-[a-zA-Z0-9_-]+/g,\n23: /sk-ant-api\\d+-[a-zA-Z0-9_-]+/g,\n24: ],\n25: validator: (key: string) => /^sk-ant(-api\\d+)?-[a-zA-Z0-9_-]+$/.test(key),\n26: envVar: 'ANTHROPIC_API_KEY',\n27: description: 'Anthropic API keys',\n28: });\n29: \n30: // Configure spotclean for error sanitization\n31: configureErrorSanitizer({\n32: enabled: true,\n33: environment: process.env.NODE_ENV === 'production' ? 'production' : 'development',\n34: includeCorrelationId: true,\n35: sanitizeStackTraces: process.env.NODE_ENV === 'production',\n36: maxMessageLength: 500,\n37: });\n38: \n39: configureSecretGuard({\n40: enabled: true,\n41: redactionText: '[REDACTED]',\n42: preservePartial: false,\n43: preserveLength: 0,\n44: customPatterns: [\n45: { name: 'anthropic', pattern: /sk-ant-[a-zA-Z0-9_-]+/g, description: 'Anthropic API key' },\n46: { name: 'anthropic-api', pattern: /sk-ant-api\\d+-[a-zA-Z0-9_-]+/g, description: 'Anthropic API key' },\n47: ],\n48: });\n49: \n50: // ===== INLINE TYPES (from 'execution' package) =====\n51: \n52: export type Model = string;\n53: \n54: export interface Message {\n55: role: 'user' | 'assistant' | 'system' | 'developer' | 'tool';\n56: content: string | string[] | null;\n57: name?: string;\n58: }\n59: \n60: export interface Request {\n61: messages: Message[];\n62: model: Model;\n63: responseFormat?: any;\n64: validator?: any;\n65: addMessage(message: Message): void;\n66: }\n67: \n68: export interface ProviderResponse {\n69: content: string;\n70: model: string;\n71: usage?: {\n72: inputTokens: number;\n73: outputTokens: number;\n74: };\n75: toolCalls?: Array<{\n76: id: string;\n77: type: 'function';\n78: function: {\n79: name: string;\n80: arguments: string;\n81: };\n82: }>;\n83: }\n84: \n85: export interface ExecutionOptions {\n86: apiKey?: string;\n87: model?: string;\n88: temperature?: number;\n89: maxTokens?: number;\n90: timeout?: number;\n91: retries?: number;\n92: }\n93: \n94: export interface Provider {\n95: readonly name: string;\n96: execute(request: Request, options?: ExecutionOptions): Promise<ProviderResponse>;\n97: supportsModel?(model: Model): boolean;\n98: }\n99: \n100: /**\n101: * Anthropic Provider implementation\n102: */\n103: export class AnthropicProvider implements Provider {\n104: readonly name = 'anthropic';\n105: \n106: /**\n107: * Check if this provider supports a given model\n108: */\n109: supportsModel(model: Model): boolean {\n110: if (!model) return false;\n111: return model.startsWith('claude');\n112: }\n113: \n114: /**\n115: * Execute a request against Anthropic\n116: */\n117: async execute(\n118: request: Request,\n119: options: ExecutionOptions = {}\n120: ): Promise<ProviderResponse> {\n121: const apiKey = options.apiKey || process.env.ANTHROPIC_API_KEY;\n122: \n123: if (!apiKey) {\n124: throw new Error('Anthropic API key is required. Set ANTHROPIC_API_KEY environment variable.');\n125: }\n126: \n127: // Validate key format\n128: const validation = redactor.validateKey(apiKey, 'anthropic');\n129: if (!validation.valid) {\n130: throw new Error('Invalid Anthropic API key format');\n131: }\n132: \n133: try {\n134: const client = new Anthropic({ apiKey });\n135: \n136: const model = options.model || request.model || 'claude-3-opus-20240229';\n137: \n138: // Anthropic separates system prompt from messages\n139: let systemPrompt = '';\n140: const messages: Anthropic.MessageParam[] = [];\n141: \n142: for (const msg of request.messages) {\n143: if (msg.role === 'system' || msg.role === 'developer') {\n144: systemPrompt +=\n145: (typeof msg.content === 'string'\n146: ? msg.content\n147: : JSON.stringify(msg.content)) + '\\n\\n';\n148: } else {\n149: messages.push({\n150: role: msg.role as 'user' | 'assistant',\n151: content:\n152: typeof msg.content === 'string'\n153: ? msg.content\n154: : JSON.stringify(msg.content),\n155: });\n156: }\n157: }\n158: \n159: const response = await client.messages.create({\n160: model: model,\n161: system: systemPrompt.trim() || undefined,\n162: messages: messages,\n163: max_tokens: options.maxTokens || 4096,\n164: temperature: options.temperature,\n165: ...(request.responseFormat?.type === 'json_schema'\n166: ? {\n167: tools: [\n168: {\n169: name: request.responseFormat.json_schema.name,\n170: description:\n171: request.responseFormat.json_schema.description ||\n172: 'Output data in this structured format',\n173: input_schema:\n174: request.responseFormat.json_schema.schema,\n175: },\n176: ],\n177: tool_choice: {\n178: type: 'tool' as const,\n179: name: request.responseFormat.json_schema.name,\n180: },\n181: }\n182: : {}),\n183: });\n184: \n185: // Handle ContentBlock\n186: let text = '';\n187: \n188: if (request.responseFormat?.type === 'json_schema') {\n189: const toolUseBlock = response.content.find(\n190: (block) => block.type === 'tool_use'\n191: );\n192: if (toolUseBlock && toolUseBlock.type === 'tool_use') {\n193: text = JSON.stringify(toolUseBlock.input, null, 2);\n194: }\n195: } else {\n196: const contentBlock = response.content[0];\n197: text = contentBlock.type === 'text' ? contentBlock.text : '';\n198: }\n199: \n200: return {\n201: content: text,\n202: model: response.model,\n203: usage: {\n204: inputTokens: response.usage.input_tokens,\n205: outputTokens: response.usage.output_tokens,\n206: },\n207: };\n208: } catch (error) {\n209: // Sanitize error to remove any API keys from error messages\n210: // Use spotclean for comprehensive error sanitization\n211: throw createSafeError(error as Error, { provider: 'anthropic' });\n212: }\n213: }\n214: }\n215: \n216: /**\n217: * Create a new Anthropic provider instance\n218: */\n219: export function createAnthropicProvider(): AnthropicProvider {\n220: return new AnthropicProvider();\n221: }\n222: \n223: /**\n224: * Package version\n225: */\n226: export const VERSION = '0.0.1';\n227: \n228: export default AnthropicProvider;\n229: ",
208
+ "name": "get_file_content"
209
+ },
210
+ {
211
+ "role": "tool",
212
+ "tool_call_id": "call_iSqtllNZxaTkIRj5nrpzqsNY",
213
+ "content": "1: {\n2: \"name\": \"@riotprompt/execution-anthropic\",\n3: \"version\": \"1.0.3\",\n4: \"description\": \"Anthropic Claude provider for execution interface\",\n5: \"type\": \"module\",\n6: \"main\": \"./dist/index.js\",\n7: \"types\": \"./dist/index.d.ts\",\n8: \"exports\": {\n9: \".\": {\n10: \"types\": \"./dist/index.d.ts\",\n11: \"import\": \"./dist/index.js\"\n12: }\n13: },\n14: \"engines\": {\n15: \"node\": \">=24.0.0\"\n16: },\n17: \"scripts\": {\n18: \"clean\": \"rm -rf dist\",\n19: \"build\": \"vite build\",\n20: \"test\": \"vitest run --coverage\",\n21: \"test:coverage\": \"vitest run --coverage\",\n22: \"lint\": \"eslint src\",\n23: \"precommit\": \"npm run build && npm run lint && npm run test\",\n24: \"prepublishOnly\": \"npm run clean && npm run build\"\n25: },\n26: \"keywords\": [\n27: \"llm\",\n28: \"anthropic\",\n29: \"claude\",\n30: \"execution\",\n31: \"provider\"\n32: ],\n33: \"author\": \"Tim O'Brien <tobrien@discursive.com>\",\n34: \"license\": \"Apache-2.0\",\n35: \"repository\": {\n36: \"type\": \"git\",\n37: \"url\": \"https://github.com/kjerneverk/execution-anthropic\"\n38: },\n39: \"dependencies\": {\n40: \"@anthropic-ai/sdk\": \"^0.52.0\",\n41: \"@utilarium/offrecord\": \"^0.0.3\",\n42: \"@utilarium/spotclean\": \"^0.0.4\"\n43: },\n44: \"devDependencies\": {\n45: \"@types/node\": \"^25.0.6\",\n46: \"@typescript-eslint/eslint-plugin\": \"^8.33.1\",\n47: \"@typescript-eslint/parser\": \"^8.33.1\",\n48: \"@vitest/coverage-v8\": \"^3.2.4\",\n49: \"ajv\": \"^8.17.1\",\n50: \"eslint\": \"^9.28.0\",\n51: \"globals\": \"^16.2.0\",\n52: \"typescript\": \"^5.8.3\",\n53: \"vite\": \"^7.0.4\",\n54: \"vite-plugin-dts\": \"^4.5.4\",\n55: \"vitest\": \"^3.2.4\"\n56: }\n57: }\n58: ",
214
+ "name": "get_file_content"
215
+ },
216
+ {
217
+ "role": "tool",
218
+ "tool_call_id": "call_vV6it6Rx8gLxiESCOEKBqzAV",
219
+ "content": "1: import { defineConfig } from \"vite\";\n2: import dts from \"vite-plugin-dts\";\n3: \n4: export default defineConfig({\n5: build: {\n6: lib: {\n7: entry: \"src/index.ts\",\n8: name: \"execution-anthropic\",\n9: fileName: () => \"index.js\",\n10: formats: [\"es\"],\n11: },\n12: rollupOptions: {\n13: external: [\n14: \"@anthropic-ai/sdk\",\n15: \"execution\",\n16: \"@utilarium/offrecord\",\n17: \"@utilarium/spotclean\",\n18: \"node:crypto\",\n19: ],\n20: },\n21: sourcemap: true,\n22: minify: false,\n23: },\n24: plugins: [dts({ rollupTypes: true })],\n25: });\n26: ",
220
+ "name": "get_file_content"
221
+ },
222
+ {
223
+ "role": "assistant",
224
+ "content": null,
225
+ "tool_calls": [
226
+ {
227
+ "id": "call_GgLMLAc3aMwhayLOMcnS0N4k",
228
+ "type": "function",
229
+ "function": {
230
+ "name": "search_codebase",
231
+ "arguments": "{\"query\":\"VERSION =\",\"fileTypes\":[\"ts\",\"js\"],\"contextLines\":2}"
232
+ }
233
+ }
234
+ ]
235
+ },
236
+ {
237
+ "role": "tool",
238
+ "tool_call_id": "call_GgLMLAc3aMwhayLOMcnS0N4k",
239
+ "content": "src/index.ts-224- * Package version\nsrc/index.ts-225- */\nsrc/index.ts:226:export const VERSION = '0.0.1';\nsrc/index.ts-227-\nsrc/index.ts-228-export default AnthropicProvider;\n",
240
+ "name": "search_codebase"
241
+ },
242
+ {
243
+ "role": "assistant",
244
+ "content": null,
245
+ "tool_calls": [
246
+ {
247
+ "id": "call_sTZuzAUFLN5y7ta8Z6iCRJoL",
248
+ "type": "function",
249
+ "function": {
250
+ "name": "get_file_dependencies",
251
+ "arguments": "{\"filePaths\": [\"src/index.ts\", \"vite.config.ts\", \"package.json\"]}"
252
+ }
253
+ },
254
+ {
255
+ "id": "call_KZ1qHa0ohBCJqTL5W3X0j43i",
256
+ "type": "function",
257
+ "function": {
258
+ "name": "get_related_tests",
259
+ "arguments": "{\"filePaths\": [\"src/index.ts\"]}"
260
+ }
261
+ }
262
+ ]
263
+ },
264
+ {
265
+ "role": "tool",
266
+ "tool_call_id": "call_sTZuzAUFLN5y7ta8Z6iCRJoL",
267
+ "content": "Files importing src/index.ts:\ntests/index.test.ts\n",
268
+ "name": "get_file_dependencies"
269
+ },
270
+ {
271
+ "role": "tool",
272
+ "tool_call_id": "call_KZ1qHa0ohBCJqTL5W3X0j43i",
273
+ "content": "Found related test files:\nsrc/index.ts",
274
+ "name": "get_related_tests"
275
+ },
276
+ {
277
+ "role": "assistant",
278
+ "content": null,
279
+ "tool_calls": [
280
+ {
281
+ "id": "call_YujvlmEBMkhB6kgyk1uH4BGd",
282
+ "type": "function",
283
+ "function": {
284
+ "name": "get_file_content",
285
+ "arguments": "{\"filePath\":\"tests/index.test.ts\",\"includeLineNumbers\":true}"
286
+ }
287
+ }
288
+ ]
289
+ },
290
+ {
291
+ "role": "tool",
292
+ "tool_call_id": "call_YujvlmEBMkhB6kgyk1uH4BGd",
293
+ "content": "1: /**\n2: * Tests for execution-anthropic package\n3: */\n4: \n5: import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';\n6: import {\n7: AnthropicProvider,\n8: createAnthropicProvider,\n9: VERSION,\n10: type Message,\n11: type Request,\n12: type ExecutionOptions,\n13: type ProviderResponse,\n14: type Provider,\n15: } from '../src/index.js';\n16: \n17: describe('AnthropicProvider', () => {\n18: let provider: AnthropicProvider;\n19: \n20: beforeEach(() => {\n21: provider = new AnthropicProvider();\n22: });\n23: \n24: describe('name', () => {\n25: it('should have name \"anthropic\"', () => {\n26: expect(provider.name).toBe('anthropic');\n27: });\n28: });\n29: \n30: describe('supportsModel', () => {\n31: it('should support Claude 3 models', () => {\n32: expect(provider.supportsModel('claude-3-opus-20240229')).toBe(true);\n33: expect(provider.supportsModel('claude-3-sonnet-20240229')).toBe(true);\n34: expect(provider.supportsModel('claude-3-haiku-20240307')).toBe(true);\n35: });\n36: \n37: it('should support Claude 3.5 models', () => {\n38: expect(provider.supportsModel('claude-3-5-sonnet-20240620')).toBe(true);\n39: expect(provider.supportsModel('claude-3-5-haiku-20241022')).toBe(true);\n40: });\n41: \n42: it('should support Claude 4 models', () => {\n43: expect(provider.supportsModel('claude-4-opus')).toBe(true);\n44: expect(provider.supportsModel('claude-sonnet-4-20250514')).toBe(true);\n45: });\n46: \n47: it('should not support GPT models', () => {\n48: expect(provider.supportsModel('gpt-4')).toBe(false);\n49: expect(provider.supportsModel('gpt-4o')).toBe(false);\n50: expect(provider.supportsModel('gpt-3.5-turbo')).toBe(false);\n51: });\n52: \n53: it('should not support Gemini models', () => {\n54: expect(provider.supportsModel('gemini-1.5-pro')).toBe(false);\n55: expect(provider.supportsModel('gemini-1.5-flash')).toBe(false);\n56: });\n57: \n58: it('should return false for empty/undefined model', () => {\n59: expect(provider.supportsModel('')).toBe(false);\n60: });\n61: });\n62: \n63: describe('execute', () => {\n64: const originalEnv = process.env;\n65: \n66: beforeEach(() => {\n67: process.env = { ...originalEnv };\n68: delete process.env.ANTHROPIC_API_KEY;\n69: });\n70: \n71: afterEach(() => {\n72: process.env = originalEnv;\n73: });\n74: \n75: it('should throw error when no API key is provided', async () => {\n76: const request: Request = {\n77: messages: [{ role: 'user', content: 'Hello' }],\n78: model: 'claude-3-opus-20240229',\n79: addMessage: vi.fn(),\n80: };\n81: \n82: await expect(provider.execute(request)).rejects.toThrow(\n83: 'Anthropic API key is required'\n84: );\n85: });\n86: \n87: it('should throw error when API key is empty string', async () => {\n88: const request: Request = {\n89: messages: [{ role: 'user', content: 'Hello' }],\n90: model: 'claude-3-opus-20240229',\n91: addMessage: vi.fn(),\n92: };\n93: \n94: await expect(provider.execute(request, { apiKey: '' })).rejects.toThrow(\n95: 'Anthropic API key is required'\n96: );\n97: });\n98: });\n99: \n100: describe('implements Provider interface', () => {\n101: it('should satisfy Provider interface', () => {\n102: const p: Provider = provider;\n103: expect(p.name).toBe('anthropic');\n104: expect(typeof p.execute).toBe('function');\n105: expect(typeof p.supportsModel).toBe('function');\n106: });\n107: });\n108: });\n109: \n110: describe('createAnthropicProvider', () => {\n111: it('should create a new AnthropicProvider instance', () => {\n112: const provider = createAnthropicProvider();\n113: expect(provider).toBeInstanceOf(AnthropicProvider);\n114: expect(provider.name).toBe('anthropic');\n115: });\n116: });\n117: \n118: describe('VERSION', () => {\n119: it('should export version string', () => {\n120: expect(VERSION).toBe('0.0.1');\n121: });\n122: });\n123: \n124: describe('Type exports', () => {\n125: it('should export Message type', () => {\n126: const msg: Message = {\n127: role: 'user',\n128: content: 'Hello',\n129: };\n130: expect(msg.role).toBe('user');\n131: expect(msg.content).toBe('Hello');\n132: });\n133: \n134: it('should support all message roles', () => {\n135: const roles: Message['role'][] = ['user', 'assistant', 'system', 'developer', 'tool'];\n136: roles.forEach(role => {\n137: const msg: Message = { role, content: 'test' };\n138: expect(msg.role).toBe(role);\n139: });\n140: });\n141: \n142: it('should support array content', () => {\n143: const msg: Message = {\n144: role: 'user',\n145: content: ['Hello', 'World'],\n146: };\n147: expect(Array.isArray(msg.content)).toBe(true);\n148: });\n149: \n150: it('should support null content', () => {\n151: const msg: Message = {\n152: role: 'assistant',\n153: content: null,\n154: };\n155: expect(msg.content).toBeNull();\n156: });\n157: \n158: it('should support optional name field', () => {\n159: const msg: Message = {\n160: role: 'user',\n161: content: 'Hello',\n162: name: 'test-user',\n163: };\n164: expect(msg.name).toBe('test-user');\n165: });\n166: \n167: it('should export ExecutionOptions type', () => {\n168: const opts: ExecutionOptions = {\n169: apiKey: 'test-key',\n170: model: 'claude-3-opus-20240229',\n171: temperature: 0.7,\n172: maxTokens: 1000,\n173: timeout: 30000,\n174: retries: 3,\n175: };\n176: expect(opts.apiKey).toBe('test-key');\n177: expect(opts.temperature).toBe(0.7);\n178: });\n179: \n180: it('should export ProviderResponse type', () => {\n181: const response: ProviderResponse = {\n182: content: 'Hello!',\n183: model: 'claude-3-opus-20240229',\n184: usage: {\n185: inputTokens: 10,\n186: outputTokens: 5,\n187: },\n188: };\n189: expect(response.content).toBe('Hello!');\n190: expect(response.usage?.inputTokens).toBe(10);\n191: });\n192: \n193: it('should support toolCalls in ProviderResponse', () => {\n194: const response: ProviderResponse = {\n195: content: '',\n196: model: 'claude-3-opus-20240229',\n197: toolCalls: [\n198: {\n199: id: 'call_123',\n200: type: 'function',\n201: function: {\n202: name: 'get_weather',\n203: arguments: '{\"location\": \"NYC\"}',\n204: },\n205: },\n206: ],\n207: };\n208: expect(response.toolCalls).toHaveLength(1);\n209: expect(response.toolCalls?.[0].function.name).toBe('get_weather');\n210: });\n211: });\n212: \n213: ",
294
+ "name": "get_file_content"
295
+ },
296
+ {
297
+ "role": "assistant",
298
+ "content": null,
299
+ "tool_calls": [
300
+ {
301
+ "id": "call_wPgGybwceYTycA4ncq6UuUms",
302
+ "type": "function",
303
+ "function": {
304
+ "name": "get_file_history",
305
+ "arguments": "{\"filePaths\":[\"src/index.ts\"],\"limit\":5,\"format\":\"summary\"}"
306
+ }
307
+ }
308
+ ]
309
+ },
310
+ {
311
+ "role": "tool",
312
+ "tool_call_id": "call_wPgGybwceYTycA4ncq6UuUms",
313
+ "content": "5dd4963 - feat: harden Anthropic provider with API key redaction + sanitized errors (Tim O'Brien, 7 minutes ago)\n5f1438d - chore(release): bump package version to 1.0.0 (#13) (Tim O'Brien, 4 days ago)\nf3a5324 - First commit (Tim O'Brien, 3 weeks ago)\n",
314
+ "name": "get_file_history"
315
+ },
316
+ {
317
+ "role": "assistant",
318
+ "content": "RELEASE_TITLE:\n1.0.3 — Hardened Anthropic provider: API key redaction + sanitized errors\n\nRELEASE_BODY:\n## Main changes\nThis release focuses on preventing accidental leakage of Anthropic API keys and other secrets via error messages and logs, and on making failures safer to surface to callers.\n\n### Security & safety: secret redaction + error sanitization\n- **Registers Anthropic API key patterns on module load** using `@utilarium/offrecord` redaction rules (e.g., `sk-ant-...`, `sk-ant-api{n}-...`).\n- **Validates Anthropic API key format** before making requests. Invalid keys now fail fast with a clear error (`Invalid Anthropic API key format`).\n- **Sanitizes provider errors** with `@utilarium/spotclean` via `createSafeError(...)`, reducing the chance that secrets appear in thrown errors (and therefore in application logs).\n- Enables/configures Spotclean’s sanitizer + secret guard (including a default redaction text of `[REDACTED]`).\n\n**Why it matters:** if upstream libraries include request configuration or headers in error text, it’s easy to leak credentials. This release reduces that risk by default.\n\n### Build/runtime packaging updates\n- Adds new runtime dependencies:\n - `@utilarium/offrecord`\n - `@utilarium/spotclean`\n- Updates build externals in `vite.config.ts` so these dependencies (and `node:crypto`) are treated appropriately during library bundling.\n\n## Impact\n### For users\n- Expect **safer error messages** (sanitized/redacted) when requests fail.\n- If you were previously passing malformed API keys, you may now see an **earlier validation error** instead of a downstream SDK error.\n\n### For developers integrating the library\n- The module now performs some **one-time configuration at import time** (registering redaction patterns and configuring sanitization). If your application also configures `@utilarium/spotclean` globally, be aware that this package enables it with production/development-aware settings.\n\n## Breaking changes\n- No breaking changes detected in this release range. \n Note: behavior around error content and API key validation is stricter/safer, which can affect tests or log assertions that depended on unsanitized error strings."
319
+ }
320
+ ]
321
+ ```
322
+
323
+ </details>
324
+
325
+ ## Generated Release Notes
326
+
327
+ ### Title
328
+ ```
329
+ 1.0.3 — Hardened Anthropic provider: API key redaction + sanitized errors
330
+ ```
331
+
332
+ ### Body
333
+ ```markdown
334
+ ## Main changes
335
+ This release focuses on preventing accidental leakage of Anthropic API keys and other secrets via error messages and logs, and on making failures safer to surface to callers.
336
+
337
+ ### Security & safety: secret redaction + error sanitization
338
+ - **Registers Anthropic API key patterns on module load** using `@utilarium/offrecord` redaction rules (e.g., `sk-ant-...`, `sk-ant-api{n}-...`).
339
+ - **Validates Anthropic API key format** before making requests. Invalid keys now fail fast with a clear error (`Invalid Anthropic API key format`).
340
+ - **Sanitizes provider errors** with `@utilarium/spotclean` via `createSafeError(...)`, reducing the chance that secrets appear in thrown errors (and therefore in application logs).
341
+ - Enables/configures Spotclean’s sanitizer + secret guard (including a default redaction text of `[REDACTED]`).
342
+
343
+ **Why it matters:** if upstream libraries include request configuration or headers in error text, it’s easy to leak credentials. This release reduces that risk by default.
344
+
345
+ ### Build/runtime packaging updates
346
+ - Adds new runtime dependencies:
347
+ - `@utilarium/offrecord`
348
+ - `@utilarium/spotclean`
349
+ - Updates build externals in `vite.config.ts` so these dependencies (and `node:crypto`) are treated appropriately during library bundling.
350
+
351
+ ## Impact
352
+ ### For users
353
+ - Expect **safer error messages** (sanitized/redacted) when requests fail.
354
+ - If you were previously passing malformed API keys, you may now see an **earlier validation error** instead of a downstream SDK error.
355
+
356
+ ### For developers integrating the library
357
+ - The module now performs some **one-time configuration at import time** (registering redaction patterns and configuring sanitization). If your application also configures `@utilarium/spotclean` globally, be aware that this package enables it with production/development-aware settings.
358
+
359
+ ## Breaking changes
360
+ - No breaking changes detected in this release range.
361
+ Note: behavior around error content and API key validation is stricter/safer, which can affect tests or log assertions that depended on unsanitized error strings.
362
+ ```
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@kjerneverk/execution-anthropic",
3
+ "version": "1.0.4-dev.0",
4
+ "description": "Anthropic Claude provider for execution interface",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "engines": {
15
+ "node": ">=24.0.0"
16
+ },
17
+ "scripts": {
18
+ "clean": "rm -rf dist",
19
+ "build": "vite build",
20
+ "test": "vitest run --coverage",
21
+ "test:coverage": "vitest run --coverage",
22
+ "lint": "eslint src",
23
+ "precommit": "npm run build && npm run lint && npm run test",
24
+ "prepublishOnly": "npm run clean && npm run build"
25
+ },
26
+ "keywords": [
27
+ "llm",
28
+ "anthropic",
29
+ "claude",
30
+ "execution",
31
+ "provider"
32
+ ],
33
+ "author": "Tim O'Brien <tobrien@discursive.com>",
34
+ "license": "Apache-2.0",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/kjerneverk/execution-anthropic"
38
+ },
39
+ "dependencies": {
40
+ "@anthropic-ai/sdk": "^0.52.0",
41
+ "@utilarium/offrecord": "^0.0.3",
42
+ "@utilarium/spotclean": "^0.0.4"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^25.0.6",
46
+ "@typescript-eslint/eslint-plugin": "^8.33.1",
47
+ "@typescript-eslint/parser": "^8.33.1",
48
+ "@vitest/coverage-v8": "^3.2.4",
49
+ "ajv": "^8.17.1",
50
+ "eslint": "^9.28.0",
51
+ "globals": "^16.2.0",
52
+ "typescript": "^5.8.3",
53
+ "vite": "^7.0.4",
54
+ "vite-plugin-dts": "^4.5.4",
55
+ "vitest": "^3.2.4"
56
+ }
57
+ }
package/package.json~ ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@riotprompt/execution-anthropic",
3
+ "version": "1.0.0-dev.0",
4
+ "description": "Anthropic Claude provider for execution interface",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "engines": {
15
+ "node": ">=24.0.0"
16
+ },
17
+ "scripts": {
18
+ "clean": "rm -rf dist",
19
+ "build": "vite build",
20
+ "test": "vitest run --coverage",
21
+ "test:coverage": "vitest run --coverage",
22
+ "lint": "eslint src",
23
+ "precommit": "npm run build && npm run lint && npm run test",
24
+ "prepublishOnly": "npm run clean && npm run build"
25
+ },
26
+ "keywords": [
27
+ "llm",
28
+ "anthropic",
29
+ "claude",
30
+ "execution",
31
+ "provider"
32
+ ],
33
+ "author": "Tim O'Brien <tobrien@discursive.com>",
34
+ "license": "Apache-2.0",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/kjerneverk/execution-anthropic"
38
+ },
39
+ "dependencies": {
40
+ "@anthropic-ai/sdk": "^0.52.0",
41
+ "@theunwalked/offrecord": "^0.0.1",
42
+ "@theunwalked/spotclean": "^0.0.3"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^25.0.6",
46
+ "@typescript-eslint/eslint-plugin": "^8.33.1",
47
+ "@typescript-eslint/parser": "^8.33.1",
48
+ "@vitest/coverage-v8": "^3.2.4",
49
+ "eslint": "^9.28.0",
50
+ "globals": "^16.2.0",
51
+ "typescript": "^5.8.3",
52
+ "vite": "^7.0.4",
53
+ "vite-plugin-dts": "^4.5.4",
54
+ "vitest": "^3.2.4"
55
+ }
56
+ }