claude-flow 2.7.34 → 2.7.35

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,64 @@
1
+ #!/bin/bash
2
+ # Create GitHub Issue for Automatic Error Recovery
3
+ # Run this after confirming fix works in Docker/CLI
4
+
5
+ set -e
6
+
7
+ echo "šŸ“ Creating GitHub Issue for Automatic Error Recovery"
8
+ echo ""
9
+
10
+ # Check if gh CLI is installed
11
+ if ! command -v gh &> /dev/null; then
12
+ echo "āŒ GitHub CLI (gh) is not installed"
13
+ echo " Install: https://cli.github.com/"
14
+ exit 1
15
+ fi
16
+
17
+ # Check if authenticated
18
+ if ! gh auth status &> /dev/null; then
19
+ echo "āŒ Not authenticated with GitHub CLI"
20
+ echo " Run: gh auth login"
21
+ exit 1
22
+ fi
23
+
24
+ echo "āœ… GitHub CLI ready"
25
+ echo ""
26
+
27
+ # Issue title
28
+ TITLE="āœ… Fixed: Automatic recovery for WSL better-sqlite3 ENOTEMPTY error during init"
29
+
30
+ # Issue body (from template)
31
+ BODY=$(cat docs/github-issues/wsl-enotempty-automatic-recovery.md)
32
+
33
+ # Labels
34
+ LABELS="enhancement,bug-fix,wsl,user-experience,v2.7.35"
35
+
36
+ # Milestone
37
+ MILESTONE="v2.7.35"
38
+
39
+ echo "Creating issue..."
40
+ echo "Title: $TITLE"
41
+ echo "Labels: $LABELS"
42
+ echo "Milestone: $MILESTONE"
43
+ echo ""
44
+
45
+ # Create the issue
46
+ gh issue create \
47
+ --title "$TITLE" \
48
+ --body "$BODY" \
49
+ --label "$LABELS" \
50
+ --milestone "$MILESTONE"
51
+
52
+ if [ $? -eq 0 ]; then
53
+ echo ""
54
+ echo "āœ… GitHub issue created successfully!"
55
+ echo ""
56
+ echo "Next steps:"
57
+ echo "1. Add test results to the issue"
58
+ echo "2. Attach screenshots if available"
59
+ echo "3. Request review from maintainers"
60
+ else
61
+ echo ""
62
+ echo "āŒ Failed to create issue"
63
+ exit 1
64
+ fi
@@ -0,0 +1,198 @@
1
+ #!/bin/bash
2
+ # Test automatic error recovery in Docker (simulates WSL)
3
+ # Run this before creating GitHub issue
4
+
5
+ set -e
6
+
7
+ echo "🐳 Testing Automatic Error Recovery in Docker"
8
+ echo ""
9
+
10
+ # Colors for output
11
+ GREEN='\033[0;32m'
12
+ RED='\033[0;31m'
13
+ YELLOW='\033[1;33m'
14
+ NC='\033[0m' # No Color
15
+
16
+ # Test configurations
17
+ DISTROS=("ubuntu:22.04" "ubuntu:20.04" "debian:11" "debian:12")
18
+ TEST_RESULTS=()
19
+
20
+ # Function to test on a distro
21
+ test_distro() {
22
+ local distro=$1
23
+ echo ""
24
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
25
+ echo "Testing on: $distro"
26
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
27
+ echo ""
28
+
29
+ # Run test in Docker
30
+ docker run --rm -i $distro bash -c "
31
+ set -e
32
+
33
+ echo 'šŸ“¦ Installing dependencies...'
34
+ apt-get update -qq
35
+ apt-get install -y -qq curl build-essential python3 git > /dev/null 2>&1
36
+
37
+ echo 'šŸ“„ Installing Node.js...'
38
+ curl -fsSL https://deb.nodesource.com/setup_20.x | bash - > /dev/null 2>&1
39
+ apt-get install -y -qq nodejs > /dev/null 2>&1
40
+
41
+ echo 'šŸ” Node version:'
42
+ node --version
43
+ npm --version
44
+
45
+ echo ''
46
+ echo 'šŸš€ Running claude-flow init --force...'
47
+ echo ''
48
+
49
+ # Run the actual test
50
+ npx claude-flow@alpha init --force
51
+
52
+ echo ''
53
+ echo 'āœ… Test completed successfully on $distro'
54
+ " && {
55
+ echo -e "${GREEN}āœ… PASS: $distro${NC}"
56
+ TEST_RESULTS+=("PASS: $distro")
57
+ } || {
58
+ echo -e "${RED}āŒ FAIL: $distro${NC}"
59
+ TEST_RESULTS+=("FAIL: $distro")
60
+ }
61
+ }
62
+
63
+ # Function to test with corrupted cache simulation
64
+ test_corrupted_cache() {
65
+ echo ""
66
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
67
+ echo "Testing with corrupted npm cache simulation"
68
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
69
+ echo ""
70
+
71
+ docker run --rm -i ubuntu:22.04 bash -c "
72
+ set -e
73
+
74
+ apt-get update -qq
75
+ apt-get install -y -qq curl build-essential python3 git > /dev/null 2>&1
76
+ curl -fsSL https://deb.nodesource.com/setup_20.x | bash - > /dev/null 2>&1
77
+ apt-get install -y -qq nodejs > /dev/null 2>&1
78
+
79
+ echo 'šŸ’„ Simulating corrupted npm cache...'
80
+ mkdir -p ~/.npm/_npx/test-corrupt/node_modules/better-sqlite3
81
+ touch ~/.npm/_npx/test-corrupt/node_modules/better-sqlite3/.lock
82
+
83
+ echo ''
84
+ echo 'šŸš€ Running claude-flow init --force with corrupted cache...'
85
+ echo ''
86
+
87
+ npx claude-flow@alpha init --force
88
+
89
+ echo ''
90
+ echo 'āœ… Recovery from corrupted cache successful'
91
+ " && {
92
+ echo -e "${GREEN}āœ… PASS: Corrupted cache recovery${NC}"
93
+ TEST_RESULTS+=("PASS: Corrupted cache recovery")
94
+ } || {
95
+ echo -e "${RED}āŒ FAIL: Corrupted cache recovery${NC}"
96
+ TEST_RESULTS+=("FAIL: Corrupted cache recovery")
97
+ }
98
+ }
99
+
100
+ # Function to test without --force flag
101
+ test_without_force() {
102
+ echo ""
103
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
104
+ echo "Testing without --force flag (3 retries max)"
105
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
106
+ echo ""
107
+
108
+ docker run --rm -i ubuntu:22.04 bash -c "
109
+ set -e
110
+
111
+ apt-get update -qq
112
+ apt-get install -y -qq curl build-essential python3 git > /dev/null 2>&1
113
+ curl -fsSL https://deb.nodesource.com/setup_20.x | bash - > /dev/null 2>&1
114
+ apt-get install -y -qq nodejs > /dev/null 2>&1
115
+
116
+ echo 'šŸš€ Running claude-flow init (no --force)...'
117
+ echo ''
118
+
119
+ npx claude-flow@alpha init
120
+
121
+ echo ''
122
+ echo 'āœ… Init without --force successful'
123
+ " && {
124
+ echo -e "${GREEN}āœ… PASS: Init without --force${NC}"
125
+ TEST_RESULTS+=("PASS: Init without --force")
126
+ } || {
127
+ echo -e "${RED}āŒ FAIL: Init without --force${NC}"
128
+ TEST_RESULTS+=("FAIL: Init without --force")
129
+ }
130
+ }
131
+
132
+ # Main test execution
133
+ echo "Starting comprehensive Docker tests..."
134
+ echo ""
135
+ echo "This will test:"
136
+ echo " - Multiple Linux distributions"
137
+ echo " - Corrupted cache recovery"
138
+ echo " - With and without --force flag"
139
+ echo ""
140
+
141
+ read -p "Continue? (y/n) " -n 1 -r
142
+ echo ""
143
+
144
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
145
+ echo "Aborted"
146
+ exit 1
147
+ fi
148
+
149
+ # Run tests
150
+ for distro in "${DISTROS[@]}"; do
151
+ test_distro "$distro"
152
+ done
153
+
154
+ test_corrupted_cache
155
+ test_without_force
156
+
157
+ # Print summary
158
+ echo ""
159
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
160
+ echo "TEST SUMMARY"
161
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
162
+ echo ""
163
+
164
+ PASS_COUNT=0
165
+ FAIL_COUNT=0
166
+
167
+ for result in "${TEST_RESULTS[@]}"; do
168
+ if [[ $result == PASS* ]]; then
169
+ echo -e "${GREEN}āœ… $result${NC}"
170
+ ((PASS_COUNT++))
171
+ else
172
+ echo -e "${RED}āŒ $result${NC}"
173
+ ((FAIL_COUNT++))
174
+ fi
175
+ done
176
+
177
+ echo ""
178
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
179
+ echo "Total: $((PASS_COUNT + FAIL_COUNT)) tests"
180
+ echo -e "${GREEN}Passed: $PASS_COUNT${NC}"
181
+ echo -e "${RED}Failed: $FAIL_COUNT${NC}"
182
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
183
+ echo ""
184
+
185
+ if [ $FAIL_COUNT -eq 0 ]; then
186
+ echo -e "${GREEN}āœ… All tests passed!${NC}"
187
+ echo ""
188
+ echo "Next steps:"
189
+ echo "1. Review test results above"
190
+ echo "2. Run: bash scripts/create-github-issue.sh"
191
+ echo "3. Update issue with test results"
192
+ exit 0
193
+ else
194
+ echo -e "${RED}āŒ Some tests failed${NC}"
195
+ echo ""
196
+ echo "Please fix failing tests before creating GitHub issue"
197
+ exit 1
198
+ fi
@@ -5,6 +5,7 @@ import { createSwarmCommands } from './swarm-commands.js';
5
5
  import { createSparcEnvironment } from './sparc-environment.js';
6
6
  import { createClaudeConfig } from './claude-config.js';
7
7
  import { createBatchToolsGuide } from './batch-tools.js';
8
+ import { errorRecovery } from '../../utils/error-recovery.js';
8
9
 
9
10
  export interface InitOptions {
10
11
  sparc?: boolean;
@@ -12,56 +13,85 @@ export interface InitOptions {
12
13
  }
13
14
 
14
15
  export async function initCommand(options: InitOptions = {}) {
15
- try {
16
- const fs = await import('fs/promises');
17
- const path = await import('path');
16
+ // Wrap entire initialization in retry logic with automatic recovery
17
+ return errorRecovery.retryWithRecovery(
18
+ async () => {
19
+ try {
20
+ const fs = await import('fs/promises');
21
+ const path = await import('path');
18
22
 
19
- printSuccess('Initializing Claude-Flow project...');
23
+ printSuccess('Initializing Claude-Flow project...');
20
24
 
21
- // Phase 1: Create directory structure
22
- console.log('\nšŸ“ Phase 1: Creating directory structure...');
23
- await createDirectoryStructure();
25
+ // Check WSL environment and apply fixes proactively
26
+ if (errorRecovery.isWSL()) {
27
+ console.log('šŸ” WSL environment detected');
28
+ const wslCheck = await errorRecovery.recoverWSLErrors();
29
+ if (wslCheck.recovered) {
30
+ console.log('āœ… WSL environment optimized\n');
31
+ }
32
+ }
24
33
 
25
- // Phase 2: Create base configuration
26
- console.log('\nāš™ļø Phase 2: Creating configuration...');
27
- await createClaudeConfig(options);
34
+ // Phase 1: Create directory structure
35
+ console.log('\nšŸ“ Phase 1: Creating directory structure...');
36
+ await createDirectoryStructure();
28
37
 
29
- // Phase 3: Create swarm commands and documentation
30
- console.log('\nšŸ¤– Phase 3: Creating swarm commands...');
31
- await createSwarmCommands();
38
+ // Phase 2: Create base configuration
39
+ console.log('\nāš™ļø Phase 2: Creating configuration...');
40
+ await createClaudeConfig(options);
32
41
 
33
- // Phase 4: Create batch tools guides
34
- console.log('\nšŸ”§ Phase 4: Creating batch tools guides...');
35
- await createBatchToolsGuide();
42
+ // Phase 3: Create swarm commands and documentation
43
+ console.log('\nšŸ¤– Phase 3: Creating swarm commands...');
44
+ await createSwarmCommands();
36
45
 
37
- // Phase 5: SPARC environment (if requested)
38
- if (options.sparc) {
39
- console.log('\nšŸš€ Phase 5: Creating SPARC environment...');
40
- await createSparcEnvironment();
41
- }
46
+ // Phase 4: Create batch tools guides
47
+ console.log('\nšŸ”§ Phase 4: Creating batch tools guides...');
48
+ await createBatchToolsGuide();
49
+
50
+ // Phase 5: SPARC environment (if requested)
51
+ if (options.sparc) {
52
+ console.log('\nšŸš€ Phase 5: Creating SPARC environment...');
53
+ await createSparcEnvironment();
54
+ }
55
+
56
+ // Success summary
57
+ console.log('\nšŸŽ‰ Project initialized successfully!');
58
+ console.log(' šŸ“ Created .claude/ directory structure');
59
+ console.log(' šŸ“‹ Created comprehensive swarm command documentation');
60
+ console.log(' šŸ”§ Created batch tools coordination guides');
61
+ console.log(' šŸ“– Created detailed usage examples with orchestration');
42
62
 
43
- // Success summary
44
- console.log('\nšŸŽ‰ Project initialized successfully!');
45
- console.log(' šŸ“ Created .claude/ directory structure');
46
- console.log(' šŸ“‹ Created comprehensive swarm command documentation');
47
- console.log(' šŸ”§ Created batch tools coordination guides');
48
- console.log(' šŸ“– Created detailed usage examples with orchestration');
63
+ console.log('\n Next steps:');
64
+ console.log(' 1. Run "claude-flow swarm --help" to see swarm options');
65
+ console.log(' 2. Check .claude/commands/swarm/ for detailed documentation');
66
+ console.log(' 3. Review batch tools guide for orchestration patterns');
67
+ console.log(' 4. Run "claude-flow help" for all available commands');
49
68
 
50
- console.log('\n Next steps:');
51
- console.log(' 1. Run "claude-flow swarm --help" to see swarm options');
52
- console.log(' 2. Check .claude/commands/swarm/ for detailed documentation');
53
- console.log(' 3. Review batch tools guide for orchestration patterns');
54
- console.log(' 4. Run "claude-flow help" for all available commands');
69
+ if (options.sparc) {
70
+ console.log(' 5. Run "claude-flow sparc modes" to see available SPARC modes');
71
+ console.log(' 6. Use TodoWrite/TodoRead for task coordination');
72
+ console.log(' 7. Use Task tool for parallel agent execution');
73
+ }
74
+ } catch (error) {
75
+ // Attempt automatic error recovery
76
+ const recovery = await errorRecovery.recoverInitErrors(error);
55
77
 
56
- if (options.sparc) {
57
- console.log(' 5. Run "claude-flow sparc modes" to see available SPARC modes');
58
- console.log(' 6. Use TodoWrite/TodoRead for task coordination');
59
- console.log(' 7. Use Task tool for parallel agent execution');
78
+ if (recovery.recovered) {
79
+ console.log('āœ… Recovered from error, retrying initialization...\n');
80
+ throw error; // Trigger retry
81
+ } else {
82
+ printError(
83
+ `Failed to initialize project: ${error instanceof Error ? error.message : String(error)}`,
84
+ );
85
+ throw error;
86
+ }
87
+ }
88
+ },
89
+ {
90
+ maxRetries: options.force ? 5 : 3,
91
+ delay: 1000,
92
+ onRetry: (attempt, error) => {
93
+ console.log(`\nšŸ”„ Retry attempt ${attempt} after error recovery...`);
94
+ }
60
95
  }
61
- } catch (error) {
62
- printError(
63
- `Failed to initialize project: ${error instanceof Error ? error.message : String(error)}`,
64
- );
65
- throw error;
66
- }
96
+ );
67
97
  }
@@ -12,6 +12,8 @@ export class DatabaseManager implements IDatabaseProvider {
12
12
  private dbType: 'sqlite' | 'json';
13
13
  private dbPath: string;
14
14
  private initialized: boolean = false;
15
+ private retryCount: number = 0;
16
+ private maxRetries: number = 3;
15
17
 
16
18
  constructor(dbType: 'sqlite' | 'json' = 'sqlite', dbPath?: string) {
17
19
  this.dbType = dbType;
@@ -19,18 +21,36 @@ export class DatabaseManager implements IDatabaseProvider {
19
21
 
20
22
  // Try SQLite first, fallback to JSON if needed
21
23
  if (this.dbType === 'sqlite') {
22
- try {
23
- this.provider = new SQLiteProvider(this.dbPath);
24
- } catch (error) {
25
- console.warn('SQLite not available, falling back to JSON storage:', error);
26
- this.provider = new JSONProvider(this.dbPath.replace('.sqlite', '.json'));
27
- this.dbType = 'json';
28
- }
24
+ this.provider = this.initializeSQLiteWithRecovery();
29
25
  } else {
30
26
  this.provider = new JSONProvider(this.dbPath);
31
27
  }
32
28
  }
33
29
 
30
+ /**
31
+ * Initialize SQLite with automatic error recovery
32
+ */
33
+ private initializeSQLiteWithRecovery(): IDatabaseProvider {
34
+ try {
35
+ return new SQLiteProvider(this.dbPath);
36
+ } catch (error) {
37
+ const errorMsg = error instanceof Error ? error.message : String(error);
38
+
39
+ // Check if it's an npm cache error
40
+ if (errorMsg.includes('ENOTEMPTY') || errorMsg.includes('better-sqlite3')) {
41
+ console.warn('āš ļø SQLite initialization failed due to npm cache error');
42
+ console.warn(' Will attempt automatic recovery during initialize()');
43
+ } else {
44
+ console.warn('SQLite not available, falling back to JSON storage:', error);
45
+ }
46
+
47
+ // Fallback to JSON for now
48
+ this.provider = new JSONProvider(this.dbPath.replace('.sqlite', '.json'));
49
+ this.dbType = 'json';
50
+ return this.provider;
51
+ }
52
+ }
53
+
34
54
  private getDefaultPath(): string {
35
55
  const baseDir = path.join(process.cwd(), '.claude-flow');
36
56
  return this.dbType === 'sqlite'
@@ -40,8 +60,34 @@ export class DatabaseManager implements IDatabaseProvider {
40
60
 
41
61
  async initialize(): Promise<void> {
42
62
  await fs.ensureDir(path.dirname(this.dbPath));
43
- await this.provider.initialize();
44
- this.initialized = true;
63
+
64
+ try {
65
+ await this.provider.initialize();
66
+ this.initialized = true;
67
+ } catch (error) {
68
+ // If JSON provider failed, just propagate the error
69
+ if (this.dbType === 'json') {
70
+ throw error;
71
+ }
72
+
73
+ // For SQLite errors, attempt recovery
74
+ const errorMsg = error instanceof Error ? error.message : String(error);
75
+ if (this.retryCount < this.maxRetries) {
76
+ console.warn(`āš ļø Database initialization failed (attempt ${this.retryCount + 1}/${this.maxRetries})`);
77
+ console.warn(` Error: ${errorMsg}`);
78
+
79
+ // Attempt to recover by switching to JSON
80
+ console.log('šŸ”„ Switching to JSON storage as fallback...');
81
+ this.provider = new JSONProvider(this.dbPath.replace('.sqlite', '.json'));
82
+ this.dbType = 'json';
83
+ this.retryCount++;
84
+
85
+ // Retry initialization with JSON provider
86
+ await this.initialize();
87
+ } else {
88
+ throw error;
89
+ }
90
+ }
45
91
  }
46
92
 
47
93
  async store(key: string, value: any, namespace: string = 'default'): Promise<void> {