@boostecom/provider 0.0.1

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 (70) hide show
  1. package/README.md +90 -0
  2. package/dist/index.cjs +2522 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +848 -0
  5. package/dist/index.d.ts +848 -0
  6. package/dist/index.js +2484 -0
  7. package/dist/index.js.map +1 -0
  8. package/docs/content/README.md +337 -0
  9. package/docs/content/agent-teams.mdx +324 -0
  10. package/docs/content/api.mdx +757 -0
  11. package/docs/content/best-practices.mdx +624 -0
  12. package/docs/content/examples.mdx +675 -0
  13. package/docs/content/guide.mdx +516 -0
  14. package/docs/content/index.mdx +99 -0
  15. package/docs/content/installation.mdx +246 -0
  16. package/docs/content/skills.mdx +548 -0
  17. package/docs/content/troubleshooting.mdx +588 -0
  18. package/docs/examples/README.md +499 -0
  19. package/docs/examples/abort-signal.ts +125 -0
  20. package/docs/examples/agent-teams.ts +122 -0
  21. package/docs/examples/basic-usage.ts +73 -0
  22. package/docs/examples/check-cli.ts +51 -0
  23. package/docs/examples/conversation-history.ts +69 -0
  24. package/docs/examples/custom-config.ts +90 -0
  25. package/docs/examples/generate-object-constraints.ts +209 -0
  26. package/docs/examples/generate-object.ts +211 -0
  27. package/docs/examples/hooks-callbacks.ts +63 -0
  28. package/docs/examples/images.ts +76 -0
  29. package/docs/examples/integration-test.ts +241 -0
  30. package/docs/examples/limitations.ts +150 -0
  31. package/docs/examples/logging-custom-logger.ts +99 -0
  32. package/docs/examples/logging-default.ts +55 -0
  33. package/docs/examples/logging-disabled.ts +74 -0
  34. package/docs/examples/logging-verbose.ts +64 -0
  35. package/docs/examples/long-running-tasks.ts +179 -0
  36. package/docs/examples/message-injection.ts +210 -0
  37. package/docs/examples/mid-stream-injection.ts +126 -0
  38. package/docs/examples/run-all-examples.sh +48 -0
  39. package/docs/examples/sdk-tools-callbacks.ts +49 -0
  40. package/docs/examples/skills-discovery.ts +144 -0
  41. package/docs/examples/skills-management.ts +140 -0
  42. package/docs/examples/stream-object.ts +80 -0
  43. package/docs/examples/streaming.ts +52 -0
  44. package/docs/examples/structured-output-repro.ts +227 -0
  45. package/docs/examples/tool-management.ts +215 -0
  46. package/docs/examples/tool-streaming.ts +132 -0
  47. package/docs/examples/zod4-compatibility-test.ts +290 -0
  48. package/docs/src/claude-code-language-model.test.ts +3883 -0
  49. package/docs/src/claude-code-language-model.ts +2586 -0
  50. package/docs/src/claude-code-provider.test.ts +97 -0
  51. package/docs/src/claude-code-provider.ts +179 -0
  52. package/docs/src/convert-to-claude-code-messages.images.test.ts +104 -0
  53. package/docs/src/convert-to-claude-code-messages.test.ts +193 -0
  54. package/docs/src/convert-to-claude-code-messages.ts +419 -0
  55. package/docs/src/errors.test.ts +213 -0
  56. package/docs/src/errors.ts +216 -0
  57. package/docs/src/index.test.ts +49 -0
  58. package/docs/src/index.ts +98 -0
  59. package/docs/src/logger.integration.test.ts +164 -0
  60. package/docs/src/logger.test.ts +184 -0
  61. package/docs/src/logger.ts +65 -0
  62. package/docs/src/map-claude-code-finish-reason.test.ts +120 -0
  63. package/docs/src/map-claude-code-finish-reason.ts +60 -0
  64. package/docs/src/mcp-helpers.test.ts +71 -0
  65. package/docs/src/mcp-helpers.ts +123 -0
  66. package/docs/src/message-injection.test.ts +460 -0
  67. package/docs/src/types.ts +447 -0
  68. package/docs/src/validation.test.ts +558 -0
  69. package/docs/src/validation.ts +360 -0
  70. package/package.json +124 -0
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Example: Skills Configuration
3
+ *
4
+ * This example demonstrates how to configure Skills support in Claude Code.
5
+ * Skills allow Claude to access custom tools and capabilities defined in
6
+ * your user or project settings.
7
+ *
8
+ * Skills are loaded from:
9
+ * - User settings: ~/.claude/skills/ directory
10
+ * - Project settings: .claude/skills/ directory in your project
11
+ *
12
+ * Requirements for Skills to work:
13
+ * 1. settingSources must include the sources where skills are defined
14
+ * 2. The 'Skill' tool must be allowed (in allowedTools)
15
+ *
16
+ * NOTE: If you add 'Skill' to allowedTools but forget to set settingSources,
17
+ * you'll get a validation warning - skills won't load without settingSources!
18
+ */
19
+
20
+ import { streamText } from 'ai';
21
+ import { createClaudeCode, claudeCode } from '../dist/index.js';
22
+
23
+ async function demonstrateSkills() {
24
+ console.log('🎯 Claude Code Skills Configuration Examples\n');
25
+
26
+ // ============================================
27
+ // Example 1: Default behavior (no skills)
28
+ // ============================================
29
+ console.log('1️⃣ Default behavior (Skills disabled)');
30
+ console.log(' - No settingSources configured');
31
+ console.log(' - Skills are not available');
32
+
33
+ const defaultModel = claudeCode('sonnet');
34
+ // This model cannot use skills
35
+
36
+ console.log(' Model created without skills support\n');
37
+
38
+ // ============================================
39
+ // Example 2: Enable Skills (recommended config)
40
+ // ============================================
41
+ console.log('2️⃣ Enable Skills (recommended)');
42
+ console.log(' - settingSources: ["user", "project"]');
43
+ console.log(' - allowedTools includes "Skill"');
44
+
45
+ const skillsModel = claudeCode('sonnet', {
46
+ settingSources: ['user', 'project'],
47
+ allowedTools: ['Skill', 'Read', 'Write', 'Bash'],
48
+ });
49
+
50
+ console.log(' Model created with skills support enabled\n');
51
+
52
+ // ============================================
53
+ // Example 3: Enable Skills at provider level
54
+ // ============================================
55
+ console.log('3️⃣ Enable Skills at provider level');
56
+ console.log(' - All models from this provider have Skills available');
57
+
58
+ const skillsProvider = createClaudeCode({
59
+ defaultSettings: {
60
+ settingSources: ['user', 'project'],
61
+ allowedTools: ['Skill', 'Read', 'Write', 'Bash'],
62
+ },
63
+ });
64
+
65
+ const modelFromProvider = skillsProvider('sonnet');
66
+
67
+ console.log(' Provider created with default skills support\n');
68
+
69
+ // ============================================
70
+ // Example 4: Project-only skills
71
+ // ============================================
72
+ console.log('4️⃣ Project-only skills');
73
+ console.log(' - Only load skills from project, not user settings');
74
+
75
+ const projectOnlyModel = claudeCode('sonnet', {
76
+ settingSources: ['project'],
77
+ allowedTools: ['Skill', 'Read'],
78
+ });
79
+
80
+ console.log(' Model created with project-only skills\n');
81
+
82
+ // ============================================
83
+ // Example 5: Common mistake (triggers warning)
84
+ // ============================================
85
+ console.log('5️⃣ Common mistake: Skill in allowedTools but no settingSources');
86
+ console.log(' - This will trigger a validation warning!');
87
+ console.log(' - Skills cannot load without settingSources');
88
+
89
+ // This configuration will emit a warning:
90
+ // "allowedTools includes 'Skill' but settingSources is not set"
91
+ const misconfiguredModel = claudeCode('sonnet', {
92
+ allowedTools: ['Skill', 'Read'], // Skill added, but...
93
+ // settingSources not set! Skills won't actually load.
94
+ });
95
+
96
+ console.log(' (Check console for validation warning)\n');
97
+
98
+ // ============================================
99
+ // Usage Example with Streaming
100
+ // ============================================
101
+ console.log('📝 Example Usage with streamText:');
102
+ console.log('');
103
+ console.log(`
104
+ const { textStream } = streamText({
105
+ model: claudeCode('sonnet', {
106
+ settingSources: ['user', 'project'],
107
+ allowedTools: ['Skill', 'Read', 'Write', 'Bash'],
108
+ }),
109
+ prompt: 'Use my /custom-skill to help me with this task',
110
+ });
111
+
112
+ for await (const chunk of textStream) {
113
+ process.stdout.write(chunk);
114
+ }
115
+ `);
116
+
117
+ console.log('✅ Skills configuration examples completed!\n');
118
+
119
+ console.log('📖 Key Points:');
120
+ console.log('- settingSources must be set for skills to load');
121
+ console.log("- 'Skill' must be in allowedTools to invoke skills");
122
+ console.log('- Validation warns if Skill is allowed but settingSources is missing');
123
+ console.log('- Model-level settings override provider defaults\n');
124
+
125
+ console.log('📁 Where to define Skills:');
126
+ console.log('- User: ~/.claude/skills/your-skill/SKILL.md');
127
+ console.log('- Project: .claude/skills/your-skill/SKILL.md');
128
+ console.log('- See Claude Code documentation for skill definition syntax\n');
129
+ }
130
+
131
+ // Run the demonstration
132
+ demonstrateSkills()
133
+ .then(() => {
134
+ console.log('Examples completed!');
135
+ process.exit(0);
136
+ })
137
+ .catch((error) => {
138
+ console.error('Example failed:', error);
139
+ process.exit(1);
140
+ });
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * Example: Streaming Object Generation with Partial Updates
5
+ *
6
+ * Demonstrates using streamObject() to receive incremental partial objects
7
+ * as the AI generates structured data. This enables real-time UI updates
8
+ * as each field becomes available.
9
+ */
10
+
11
+ import { createClaudeCode } from '../dist/index.js';
12
+ import { streamObject } from 'ai';
13
+ import { z } from 'zod';
14
+
15
+ const claudeCode = createClaudeCode();
16
+
17
+ // Define a schema for the structured output
18
+ const profileSchema = z.object({
19
+ name: z.string().describe('Name of the person'),
20
+ age: z.number().describe('Age in years'),
21
+ occupation: z.string().describe('Job title'),
22
+ hobbies: z.array(z.string()).describe('List of hobbies'),
23
+ bio: z.string().describe('A short biography (2-3 sentences)'),
24
+ });
25
+
26
+ async function main() {
27
+ console.log('=== Stream Object Example ===\n');
28
+ console.log('Generating a developer profile with real-time partial updates...\n');
29
+
30
+ const startTime = Date.now();
31
+ let firstPartialTime: number | null = null;
32
+ let partialCount = 0;
33
+
34
+ const { partialObjectStream, object } = streamObject({
35
+ model: claudeCode('sonnet'),
36
+ schema: profileSchema,
37
+ prompt:
38
+ 'Generate a fictional software developer profile with creative hobbies and an interesting bio.',
39
+ });
40
+
41
+ console.log('--- Streaming Progress ---\n');
42
+
43
+ for await (const partial of partialObjectStream) {
44
+ partialCount++;
45
+
46
+ if (!firstPartialTime) {
47
+ firstPartialTime = Date.now();
48
+ console.log(`[First partial received after ${firstPartialTime - startTime}ms]\n`);
49
+ }
50
+
51
+ // Show field completion progress
52
+ const hasName = 'name' in partial && partial.name;
53
+ const hasAge = 'age' in partial && partial.age !== undefined;
54
+ const hasOccupation = 'occupation' in partial && partial.occupation;
55
+ const hobbiesCount =
56
+ 'hobbies' in partial && Array.isArray(partial.hobbies) ? partial.hobbies.length : 0;
57
+ const hasBio = 'bio' in partial && partial.bio;
58
+
59
+ // Log select updates to show streaming progress
60
+ if (partialCount <= 5 || partialCount % 25 === 0) {
61
+ console.log(
62
+ ` Partial #${partialCount}: name=${hasName ? '✓' : '...'} age=${hasAge ? '✓' : '...'} occupation=${hasOccupation ? '✓' : '...'} hobbies=${hobbiesCount} bio=${hasBio ? '✓' : '...'}`
63
+ );
64
+ }
65
+ }
66
+
67
+ // Get the final validated object
68
+ const finalObject = await object;
69
+ const endTime = Date.now();
70
+
71
+ console.log('\n--- Final Object ---\n');
72
+ console.log(JSON.stringify(finalObject, null, 2));
73
+
74
+ console.log('\n--- Statistics ---');
75
+ console.log(`Total partial updates: ${partialCount}`);
76
+ console.log(`Time to first partial: ${firstPartialTime ? firstPartialTime - startTime : 0}ms`);
77
+ console.log(`Total time: ${endTime - startTime}ms`);
78
+ }
79
+
80
+ main().catch(console.error);
@@ -0,0 +1,52 @@
1
+ import { streamText } from 'ai';
2
+ import { claudeCode } from '../dist/index.js';
3
+
4
+ async function main() {
5
+ try {
6
+ console.log('Starting streaming example...\n');
7
+ const startTime = Date.now();
8
+
9
+ // Request a longer response to clearly demonstrate streaming
10
+ const result = streamText({
11
+ model: claudeCode('opus'),
12
+ prompt: `Write a short story (about 300-400 words) about a programmer who discovers
13
+ their code has become sentient. Include dialogue and describe the programmer's emotions
14
+ as they realize what's happening.`,
15
+ });
16
+
17
+ // Stream the response with visual feedback
18
+ let chunkCount = 0;
19
+ let totalChars = 0;
20
+ let firstChunkTime: number | null = null;
21
+
22
+ console.log('--- Response ---\n');
23
+
24
+ for await (const chunk of result.textStream) {
25
+ if (firstChunkTime === null) {
26
+ firstChunkTime = Date.now();
27
+ console.log(`[First chunk received after ${firstChunkTime - startTime}ms]\n`);
28
+ }
29
+ process.stdout.write(chunk);
30
+ chunkCount++;
31
+ totalChars += chunk.length;
32
+ }
33
+
34
+ const endTime = Date.now();
35
+ console.log('\n\n--- Statistics ---');
36
+ console.log(`Total chunks received: ${chunkCount}`);
37
+ console.log(`Total characters: ${totalChars}`);
38
+ console.log(`Time to first chunk: ${firstChunkTime ? firstChunkTime - startTime : 0}ms`);
39
+ console.log(`Total time: ${endTime - startTime}ms`);
40
+ console.log(`Average chunk size: ${(totalChars / chunkCount).toFixed(1)} chars`);
41
+ } catch (error) {
42
+ console.error('Error:', error);
43
+ }
44
+ }
45
+
46
+ main().catch(console.error);
47
+ // NOTE: Migrating to Claude Agent SDK:
48
+ // - System prompt is not applied by default
49
+ // - Filesystem settings (CLAUDE.md, settings.json) are not loaded by default
50
+ // To restore old behavior, set:
51
+ // systemPrompt: { type: 'preset', preset: 'claude_code' }
52
+ // settingSources: ['user', 'project', 'local']
@@ -0,0 +1,227 @@
1
+ #!/usr/bin/env tsx
2
+
3
+ /**
4
+ * Minimal Reproduction: Claude Code CLI Structured Output Silent Fallback
5
+ *
6
+ * This script demonstrates that the Claude Code CLI silently falls back to
7
+ * unstructured prose output when JSON schemas contain certain features,
8
+ * instead of returning `structured_output` or `error_max_structured_output_retries`.
9
+ *
10
+ * EXPECTED BEHAVIOR (per SDK docs):
11
+ * - Schemas with supported features → result.structured_output contains JSON
12
+ * - Schemas with unsupported features → result.subtype === 'error_max_structured_output_retries'
13
+ *
14
+ * ACTUAL BEHAVIOR:
15
+ * - Schemas with unsupported features → Silent fallback to prose text, no error
16
+ *
17
+ * Affected features:
18
+ * - `format` constraints (email, uri, date-time, etc.)
19
+ * - Complex regex patterns (lookaheads, lookbehinds, backreferences)
20
+ *
21
+ * Run: npx tsx examples/structured-output-repro.ts
22
+ */
23
+
24
+ import { query } from '@anthropic-ai/claude-agent-sdk';
25
+
26
+ interface TestCase {
27
+ name: string;
28
+ schema: Record<string, unknown>;
29
+ expectedToWork: boolean;
30
+ }
31
+
32
+ const testCases: TestCase[] = [
33
+ {
34
+ name: 'Baseline (no format, no pattern)',
35
+ schema: {
36
+ type: 'object',
37
+ properties: {
38
+ name: { type: 'string' },
39
+ email: { type: 'string' },
40
+ },
41
+ required: ['name', 'email'],
42
+ additionalProperties: false,
43
+ },
44
+ expectedToWork: true,
45
+ },
46
+ {
47
+ name: 'format: "email" only',
48
+ schema: {
49
+ type: 'object',
50
+ properties: {
51
+ name: { type: 'string' },
52
+ email: { type: 'string', format: 'email' },
53
+ },
54
+ required: ['name', 'email'],
55
+ additionalProperties: false,
56
+ },
57
+ expectedToWork: false, // Docs say supported, but CLI fails silently
58
+ },
59
+ {
60
+ name: 'format: "uri"',
61
+ schema: {
62
+ type: 'object',
63
+ properties: {
64
+ name: { type: 'string' },
65
+ website: { type: 'string', format: 'uri' },
66
+ },
67
+ required: ['name', 'website'],
68
+ additionalProperties: false,
69
+ },
70
+ expectedToWork: false,
71
+ },
72
+ {
73
+ name: 'Simple pattern (no lookahead)',
74
+ schema: {
75
+ type: 'object',
76
+ properties: {
77
+ name: { type: 'string' },
78
+ email: { type: 'string', pattern: '^[a-z]+@[a-z]+\\.[a-z]+$' },
79
+ },
80
+ required: ['name', 'email'],
81
+ additionalProperties: false,
82
+ },
83
+ expectedToWork: true,
84
+ },
85
+ {
86
+ name: 'Pattern with lookahead (Zod .email() style)',
87
+ schema: {
88
+ type: 'object',
89
+ properties: {
90
+ name: { type: 'string' },
91
+ email: {
92
+ type: 'string',
93
+ pattern:
94
+ "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
95
+ },
96
+ },
97
+ required: ['name', 'email'],
98
+ additionalProperties: false,
99
+ },
100
+ expectedToWork: false,
101
+ },
102
+ ];
103
+
104
+ async function runTest(testCase: TestCase): Promise<{
105
+ name: string;
106
+ hasStructuredOutput: boolean;
107
+ isValidJson: boolean;
108
+ subtype: string;
109
+ outputPreview: string;
110
+ }> {
111
+ let hasStructuredOutput = false;
112
+ let isValidJson = false;
113
+ let subtype = '';
114
+ let outputPreview = '';
115
+
116
+ try {
117
+ for await (const message of query({
118
+ prompt: 'Generate a user profile with name and email for Sarah.',
119
+ options: {
120
+ outputFormat: {
121
+ type: 'json_schema',
122
+ schema: testCase.schema,
123
+ },
124
+ model: 'sonnet',
125
+ maxTurns: 3,
126
+ },
127
+ })) {
128
+ if (message.type === 'result') {
129
+ subtype = message.subtype;
130
+ const structuredOutput = (message as { structured_output?: unknown }).structured_output;
131
+ hasStructuredOutput = structuredOutput !== undefined;
132
+
133
+ if (hasStructuredOutput) {
134
+ outputPreview = JSON.stringify(structuredOutput).substring(0, 60);
135
+ isValidJson = true;
136
+ } else if ('result' in message && message.result) {
137
+ outputPreview = message.result.substring(0, 60);
138
+ try {
139
+ JSON.parse(message.result);
140
+ isValidJson = true;
141
+ } catch {
142
+ isValidJson = false;
143
+ }
144
+ }
145
+ }
146
+ }
147
+ } catch (error) {
148
+ outputPreview = `Error: ${(error as Error).message}`;
149
+ }
150
+
151
+ return { name: testCase.name, hasStructuredOutput, isValidJson, subtype, outputPreview };
152
+ }
153
+
154
+ async function main() {
155
+ console.log('='.repeat(80));
156
+ console.log('Claude Code CLI Structured Output Repro');
157
+ console.log('='.repeat(80));
158
+ console.log();
159
+ console.log('Testing various JSON Schema features with outputFormat...');
160
+ console.log();
161
+
162
+ const results = [];
163
+
164
+ for (const testCase of testCases) {
165
+ process.stdout.write(`Testing: ${testCase.name}... `);
166
+ const result = await runTest(testCase);
167
+ results.push({ ...result, expectedToWork: testCase.expectedToWork });
168
+ console.log(
169
+ result.hasStructuredOutput
170
+ ? 'structured_output'
171
+ : result.isValidJson
172
+ ? 'JSON in result'
173
+ : 'PROSE'
174
+ );
175
+ }
176
+
177
+ console.log();
178
+ console.log('='.repeat(80));
179
+ console.log('RESULTS');
180
+ console.log('='.repeat(80));
181
+ console.log();
182
+ console.log(
183
+ '| Test Case | structured_output | Valid JSON | Subtype |'
184
+ );
185
+ console.log(
186
+ '|----------------------------------------|-------------------|------------|----------|'
187
+ );
188
+
189
+ for (const r of results) {
190
+ const name = r.name.padEnd(38);
191
+ const structured = (r.hasStructuredOutput ? 'YES' : 'NO').padEnd(17);
192
+ const json = (r.isValidJson ? 'YES' : 'NO').padEnd(10);
193
+ const st = r.subtype.padEnd(8);
194
+ console.log(`| ${name} | ${structured} | ${json} | ${st} |`);
195
+ }
196
+
197
+ console.log();
198
+ console.log('OUTPUT PREVIEWS:');
199
+ for (const r of results) {
200
+ console.log(` ${r.name}: ${r.outputPreview}...`);
201
+ }
202
+
203
+ console.log();
204
+ console.log('='.repeat(80));
205
+ console.log('BUG SUMMARY');
206
+ console.log('='.repeat(80));
207
+ console.log();
208
+ console.log('EXPECTED: Unsupported schema features should return:');
209
+ console.log(' - subtype: "error_max_structured_output_retries"');
210
+ console.log(' - OR: An error indicating the schema is not supported');
211
+ console.log();
212
+ console.log('ACTUAL: Unsupported schema features cause:');
213
+ console.log(' - Silent fallback to unstructured prose');
214
+ console.log(' - subtype: "success" (misleading)');
215
+ console.log(' - No structured_output field');
216
+ console.log();
217
+ console.log('AFFECTED FEATURES:');
218
+ console.log(' - format: "email", "uri", "date-time", etc. (consistently fails)');
219
+ console.log(' - pattern: Complex regex may be flaky (sometimes works, sometimes fails)');
220
+ console.log();
221
+ console.log('WORKAROUND:');
222
+ console.log(' Use simplified schemas without format constraints for generation,');
223
+ console.log(' then validate with full schema client-side after receiving output.');
224
+ console.log();
225
+ }
226
+
227
+ main().catch(console.error);