claude-code-templates 1.24.1 → 1.24.2

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.
@@ -0,0 +1,31 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ES2022",
5
+ "lib": ["ES2022"],
6
+ "types": ["@cloudflare/workers-types", "node"],
7
+ "moduleResolution": "node",
8
+ "resolveJsonModule": true,
9
+ "esModuleInterop": true,
10
+ "allowSyntheticDefaultImports": true,
11
+ "strict": true,
12
+ "skipLibCheck": true,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "isolatedModules": true,
15
+ "noEmit": true,
16
+ "baseUrl": ".",
17
+ "paths": {
18
+ "@/*": ["src/*"]
19
+ }
20
+ },
21
+ "include": [
22
+ "src/**/*.ts",
23
+ "launcher.ts",
24
+ "monitor.ts"
25
+ ],
26
+ "exclude": [
27
+ "node_modules",
28
+ "dist",
29
+ ".wrangler"
30
+ ]
31
+ }
@@ -0,0 +1,50 @@
1
+ #:schema node_modules/wrangler/config-schema.json
2
+ name = "cloudflare-claude-sandbox"
3
+ main = "src/index.ts"
4
+ compatibility_date = "2024-01-01"
5
+ compatibility_flags = ["nodejs_compat"]
6
+
7
+ # Durable Objects configuration for sandbox persistence
8
+ [[durable_objects.bindings]]
9
+ name = "Sandbox"
10
+ class_name = "Sandbox"
11
+
12
+ # Durable Object migration (required for first deployment)
13
+ [[migrations]]
14
+ tag = "v1"
15
+ new_classes = ["Sandbox"]
16
+
17
+ # Environment variables (non-secret)
18
+ [vars]
19
+ ENVIRONMENT = "production"
20
+
21
+ # Development environment configuration
22
+ [env.development]
23
+ vars = { ENVIRONMENT = "development" }
24
+
25
+ # Staging environment configuration
26
+ [env.staging]
27
+ vars = { ENVIRONMENT = "staging" }
28
+
29
+ # Resource limits
30
+ [limits]
31
+ # CPU time limit per request (milliseconds)
32
+ cpu_ms = 50
33
+
34
+ # Build configuration
35
+ [build]
36
+ command = ""
37
+
38
+ # Observability
39
+ [observability]
40
+ enabled = true
41
+
42
+ # Usage model - required for Durable Objects
43
+ [usage_model]
44
+ # Use 'bundled' for Workers Paid plan ($5/month)
45
+ # Includes 10M requests/month and unlimited Durable Objects
46
+ # For free tier, comment this out (limited functionality)
47
+ # usage_model = "bundled"
48
+
49
+ # Note: Uncomment the line above after setting up Workers Paid plan
50
+ # Or remove this section entirely for the free tier (sandbox will be limited)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-templates",
3
- "version": "1.24.1",
3
+ "version": "1.24.2",
4
4
  "description": "CLI tool to setup Claude Code configurations with framework-specific commands, automation hooks and MCP Servers for your projects",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -92,6 +92,7 @@
92
92
  "bin/",
93
93
  "src/",
94
94
  "components/sandbox/e2b/",
95
+ "components/sandbox/cloudflare/",
95
96
  "README.md"
96
97
  ],
97
98
  "devDependencies": {
package/src/index.js CHANGED
@@ -2395,10 +2395,11 @@ async function executeSandbox(options, targetDir) {
2395
2395
  let { agent, prompt } = options;
2396
2396
 
2397
2397
  // Validate sandbox provider
2398
- if (sandbox !== 'e2b') {
2399
- console.log(chalk.red('āŒ Error: Only E2B sandbox is currently supported'));
2400
- console.log(chalk.yellow('šŸ’” Available providers: e2b'));
2398
+ if (sandbox !== 'e2b' && sandbox !== 'cloudflare') {
2399
+ console.log(chalk.red('āŒ Error: Invalid sandbox provider'));
2400
+ console.log(chalk.yellow('šŸ’” Available providers: e2b, cloudflare'));
2401
2401
  console.log(chalk.gray(' Example: --sandbox e2b --prompt "Create a web app"'));
2402
+ console.log(chalk.gray(' Example: --sandbox cloudflare --prompt "Calculate factorial of 5"'));
2402
2403
  return;
2403
2404
  }
2404
2405
 
@@ -2507,28 +2508,247 @@ async function executeSandbox(options, targetDir) {
2507
2508
  // Ignore .env loading errors
2508
2509
  }
2509
2510
 
2510
- // Check for API keys (either from CLI parameters or environment variables)
2511
- const e2bKey = e2bApiKey || process.env.E2B_API_KEY;
2511
+ // Check for API keys based on sandbox provider
2512
2512
  const anthropicKey = anthropicApiKey || process.env.ANTHROPIC_API_KEY;
2513
-
2514
- if (!e2bKey) {
2515
- console.log(chalk.red('āŒ Error: E2B API key is required'));
2516
- console.log(chalk.yellow('šŸ’” Options:'));
2517
- console.log(chalk.gray(' 1. Set environment variable: E2B_API_KEY=your_key'));
2518
- console.log(chalk.gray(' 2. Use CLI parameter: --e2b-api-key your_key'));
2519
- console.log(chalk.blue(' Get your key at: https://e2b.dev/dashboard'));
2520
- return;
2513
+
2514
+ if (sandbox === 'e2b') {
2515
+ const e2bKey = e2bApiKey || process.env.E2B_API_KEY;
2516
+
2517
+ if (!e2bKey) {
2518
+ console.log(chalk.red('āŒ Error: E2B API key is required'));
2519
+ console.log(chalk.yellow('šŸ’” Options:'));
2520
+ console.log(chalk.gray(' 1. Set environment variable: E2B_API_KEY=your_key'));
2521
+ console.log(chalk.gray(' 2. Use CLI parameter: --e2b-api-key your_key'));
2522
+ console.log(chalk.blue(' Get your key at: https://e2b.dev/dashboard'));
2523
+ return;
2524
+ }
2525
+
2526
+ if (!anthropicKey) {
2527
+ console.log(chalk.red('āŒ Error: Anthropic API key is required'));
2528
+ console.log(chalk.yellow('šŸ’” Options:'));
2529
+ console.log(chalk.gray(' 1. Set environment variable: ANTHROPIC_API_KEY=your_key'));
2530
+ console.log(chalk.gray(' 2. Use CLI parameter: --anthropic-api-key your_key'));
2531
+ console.log(chalk.blue(' Get your key at: https://console.anthropic.com'));
2532
+ return;
2533
+ }
2534
+
2535
+ // Execute E2B sandbox
2536
+ await executeE2BSandbox({ sandbox, agent, prompt, command, mcp, setting, hook, e2bKey, anthropicKey }, targetDir);
2537
+
2538
+ } else if (sandbox === 'cloudflare') {
2539
+ if (!anthropicKey) {
2540
+ console.log(chalk.red('āŒ Error: Anthropic API key is required for Cloudflare sandbox'));
2541
+ console.log(chalk.yellow('šŸ’” Options:'));
2542
+ console.log(chalk.gray(' 1. Set environment variable: ANTHROPIC_API_KEY=your_key'));
2543
+ console.log(chalk.gray(' 2. Use CLI parameter: --anthropic-api-key your_key'));
2544
+ console.log(chalk.blue(' Get your key at: https://console.anthropic.com'));
2545
+ return;
2546
+ }
2547
+
2548
+ // Execute Cloudflare sandbox
2549
+ await executeCloudflareSandbox({ sandbox, agent, prompt, command, mcp, setting, hook, anthropicKey }, targetDir);
2521
2550
  }
2522
-
2523
- if (!anthropicKey) {
2524
- console.log(chalk.red('āŒ Error: Anthropic API key is required'));
2525
- console.log(chalk.yellow('šŸ’” Options:'));
2526
- console.log(chalk.gray(' 1. Set environment variable: ANTHROPIC_API_KEY=your_key'));
2527
- console.log(chalk.gray(' 2. Use CLI parameter: --anthropic-api-key your_key'));
2528
- console.log(chalk.blue(' Get your key at: https://console.anthropic.com'));
2551
+ }
2552
+
2553
+ async function executeCloudflareSandbox(options, targetDir) {
2554
+ const { agent, prompt, anthropicKey } = options;
2555
+
2556
+ console.log(chalk.blue('\nā˜ļø Cloudflare Sandbox Execution'));
2557
+ console.log(chalk.cyan('═══════════════════════════════════════'));
2558
+
2559
+ if (agent) {
2560
+ const agentList = agent.split(',');
2561
+ if (agentList.length > 1) {
2562
+ console.log(chalk.white(`šŸ“‹ Agents (${agentList.length}):`));
2563
+ agentList.forEach(a => console.log(chalk.yellow(` • ${a.trim()}`)));
2564
+ } else {
2565
+ console.log(chalk.white(`šŸ“‹ Agent: ${chalk.yellow(agent)}`));
2566
+ }
2567
+ } else {
2568
+ console.log(chalk.white(`šŸ“‹ Agent: ${chalk.yellow('default')}`));
2569
+ }
2570
+
2571
+ const truncatedPrompt = prompt.length > 80 ? prompt.substring(0, 80) + '...' : prompt;
2572
+ console.log(chalk.white(`šŸ’­ Prompt: ${chalk.cyan('"' + truncatedPrompt + '"')}`));
2573
+ console.log(chalk.white(`🌐 Provider: ${chalk.green('Cloudflare Workers')}`));
2574
+ console.log(chalk.gray('\nšŸ”§ Execution details:'));
2575
+ console.log(chalk.gray(' • Uses Claude AI for code generation'));
2576
+ console.log(chalk.gray(' • Executes in isolated Cloudflare sandbox'));
2577
+ console.log(chalk.gray(' • Global edge deployment for low latency\n'));
2578
+
2579
+ const inquirer = require('inquirer');
2580
+
2581
+ const { shouldExecute } = await inquirer.prompt([{
2582
+ type: 'confirm',
2583
+ name: 'shouldExecute',
2584
+ message: 'Execute this prompt in Cloudflare sandbox?',
2585
+ default: true
2586
+ }]);
2587
+
2588
+ if (!shouldExecute) {
2589
+ console.log(chalk.yellow('ā¹ļø Cloudflare sandbox execution cancelled by user.'));
2529
2590
  return;
2530
2591
  }
2531
-
2592
+
2593
+ try {
2594
+ console.log(chalk.blue('šŸ”® Setting up Cloudflare sandbox environment...'));
2595
+
2596
+ const spinner = ora('Installing Cloudflare sandbox component...').start();
2597
+
2598
+ // Create .claude/sandbox/cloudflare directory
2599
+ const sandboxDir = path.join(targetDir, '.claude', 'sandbox', 'cloudflare');
2600
+ await fs.ensureDir(sandboxDir);
2601
+
2602
+ // Copy Cloudflare component files
2603
+ const componentsDir = path.join(__dirname, '..', 'components', 'sandbox', 'cloudflare');
2604
+
2605
+ try {
2606
+ if (await fs.pathExists(componentsDir)) {
2607
+ console.log(chalk.gray('šŸ“¦ Using local Cloudflare component files...'));
2608
+
2609
+ // Copy all files from cloudflare directory
2610
+ await fs.copy(componentsDir, sandboxDir, {
2611
+ overwrite: true,
2612
+ filter: (src) => {
2613
+ // Exclude node_modules and build artifacts
2614
+ return !src.includes('node_modules') &&
2615
+ !src.includes('.wrangler') &&
2616
+ !src.includes('dist');
2617
+ }
2618
+ });
2619
+ } else {
2620
+ throw new Error('Cloudflare component files not found in package');
2621
+ }
2622
+ } catch (error) {
2623
+ spinner.fail(`Failed to install Cloudflare component: ${error.message}`);
2624
+ throw error;
2625
+ }
2626
+
2627
+ spinner.succeed('Cloudflare sandbox component installed successfully');
2628
+
2629
+ // Check for Node.js
2630
+ const nodeSpinner = ora('Checking Node.js environment...').start();
2631
+
2632
+ try {
2633
+ const { spawn } = require('child_process');
2634
+
2635
+ // Check Node.js version
2636
+ const checkNode = () => {
2637
+ return new Promise((resolve) => {
2638
+ const check = spawn('node', ['--version'], { stdio: 'pipe' });
2639
+ check.on('close', (code) => resolve(code === 0));
2640
+ check.on('error', () => resolve(false));
2641
+ });
2642
+ };
2643
+
2644
+ const nodeAvailable = await checkNode();
2645
+ if (!nodeAvailable) {
2646
+ nodeSpinner.fail('Node.js not found');
2647
+ console.log(chalk.red('āŒ Node.js 16.17.0+ is required for Cloudflare sandbox'));
2648
+ console.log(chalk.yellow('šŸ’” Please install Node.js and try again'));
2649
+ console.log(chalk.blue(' Visit: https://nodejs.org'));
2650
+ return;
2651
+ }
2652
+
2653
+ nodeSpinner.succeed('Node.js environment ready');
2654
+
2655
+ // Install NPM dependencies
2656
+ const depSpinner = ora('Installing Cloudflare dependencies...').start();
2657
+
2658
+ const npmInstall = spawn('npm', ['install'], {
2659
+ cwd: sandboxDir,
2660
+ stdio: 'pipe'
2661
+ });
2662
+
2663
+ let npmOutput = '';
2664
+ let npmError = '';
2665
+
2666
+ npmInstall.stdout.on('data', (data) => {
2667
+ npmOutput += data.toString();
2668
+ });
2669
+
2670
+ npmInstall.stderr.on('data', (data) => {
2671
+ npmError += data.toString();
2672
+ });
2673
+
2674
+ await new Promise((resolve, reject) => {
2675
+ npmInstall.on('close', async (npmCode) => {
2676
+ if (npmCode === 0) {
2677
+ depSpinner.succeed('Cloudflare dependencies installed successfully');
2678
+
2679
+ // Execute using launcher
2680
+ console.log(chalk.blue('šŸš€ Launching Cloudflare sandbox...'));
2681
+ console.log(chalk.gray(`šŸ“ Prompt: "${prompt.substring(0, 100)}${prompt.length > 100 ? '...' : ''}"`));
2682
+
2683
+ // Use ts-node or tsx to execute TypeScript launcher
2684
+ const launcherPath = path.join(sandboxDir, 'launcher.ts');
2685
+
2686
+ console.log(chalk.blue('šŸš€ Starting Cloudflare sandbox execution...'));
2687
+
2688
+ const sandboxExecution = spawn('npx', [
2689
+ 'tsx',
2690
+ launcherPath,
2691
+ prompt,
2692
+ agent || '',
2693
+ anthropicKey,
2694
+ 'http://localhost:8787', // Local dev server URL
2695
+ targetDir // Project root directory for file output
2696
+ ], {
2697
+ cwd: sandboxDir,
2698
+ stdio: 'inherit',
2699
+ timeout: 300000, // 5 minutes
2700
+ env: {
2701
+ ...process.env,
2702
+ ANTHROPIC_API_KEY: anthropicKey
2703
+ }
2704
+ });
2705
+
2706
+ sandboxExecution.on('close', (code) => {
2707
+ if (code === 0) {
2708
+ console.log(chalk.green('šŸŽ‰ Cloudflare sandbox execution completed successfully!'));
2709
+ resolve();
2710
+ } else if (code === null) {
2711
+ console.log(chalk.yellow('ā¹ļø Sandbox execution was cancelled'));
2712
+ resolve();
2713
+ } else {
2714
+ console.log(chalk.yellow(`āš ļø Sandbox execution finished with exit code ${code}`));
2715
+ console.log(chalk.gray('šŸ’” Check the output above for error details'));
2716
+ resolve();
2717
+ }
2718
+ });
2719
+
2720
+ sandboxExecution.on('error', (error) => {
2721
+ console.log(chalk.red(`āŒ Error executing sandbox: ${error.message}`));
2722
+ console.log(chalk.yellow('šŸ’” Make sure you have set ANTHROPIC_API_KEY'));
2723
+ reject(error);
2724
+ });
2725
+ } else {
2726
+ depSpinner.fail('Failed to install Cloudflare dependencies');
2727
+ console.log(chalk.red(`āŒ npm install failed with exit code ${npmCode}`));
2728
+ if (npmError) {
2729
+ console.log(chalk.red('Error output:'));
2730
+ console.log(chalk.gray(npmError.trim()));
2731
+ }
2732
+ reject(new Error('Failed to install dependencies'));
2733
+ }
2734
+ });
2735
+ });
2736
+
2737
+ } catch (error) {
2738
+ nodeSpinner.fail('Failed to check Node.js environment');
2739
+ console.log(chalk.red(`āŒ Error: ${error.message}`));
2740
+ throw error;
2741
+ }
2742
+
2743
+ } catch (error) {
2744
+ console.log(chalk.red(`āŒ Error setting up Cloudflare sandbox: ${error.message}`));
2745
+ console.log(chalk.yellow('šŸ’” Please check your internet connection and try again'));
2746
+ }
2747
+ }
2748
+
2749
+ async function executeE2BSandbox(options, targetDir) {
2750
+ const { agent, prompt, command, mcp, setting, hook, e2bKey, anthropicKey } = options;
2751
+
2532
2752
  // Sandbox execution confirmation
2533
2753
  console.log(chalk.blue('\nā˜ļø E2B Sandbox Execution'));
2534
2754
  console.log(chalk.cyan('═══════════════════════════════════════'));