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.
- package/CHANGELOG.md +65 -0
- package/bin/claude-flow +1 -1
- package/dist/src/cli/help-formatter.js +0 -5
- package/dist/src/cli/init/index.js +55 -33
- package/dist/src/cli/init/index.js.map +1 -1
- package/dist/src/cli/simple-cli.js +182 -172
- package/dist/src/cli/simple-cli.js.map +1 -1
- package/dist/src/core/DatabaseManager.js +39 -9
- package/dist/src/core/DatabaseManager.js.map +1 -1
- package/dist/src/core/version.js +1 -1
- package/dist/src/utils/error-recovery.js +215 -0
- package/dist/src/utils/error-recovery.js.map +1 -0
- package/dist/src/utils/metrics-reader.js +10 -0
- package/dist/src/utils/metrics-reader.js.map +1 -1
- package/docs/AUTOMATIC_ERROR_RECOVERY_v2.7.35.md +321 -0
- package/docs/CONFIRMATION_AUTOMATIC_ERROR_RECOVERY.md +384 -0
- package/docs/DOCKER_TEST_RESULTS_v2.7.35.md +305 -0
- package/docs/features/automatic-error-recovery.md +333 -0
- package/docs/github-issues/README.md +88 -0
- package/docs/github-issues/wsl-enotempty-automatic-recovery.md +470 -0
- package/docs/troubleshooting/wsl-better-sqlite3-error.md +239 -0
- package/package.json +1 -1
- package/scripts/create-github-issue.sh +64 -0
- package/scripts/test-docker-wsl.sh +198 -0
- package/src/cli/init/index.ts +72 -42
- package/src/core/DatabaseManager.ts +55 -9
- package/src/utils/error-recovery.ts +325 -0
|
@@ -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
|
package/src/cli/init/index.ts
CHANGED
|
@@ -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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
23
|
+
printSuccess('Initializing Claude-Flow project...');
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
// Phase 1: Create directory structure
|
|
35
|
+
console.log('\nš Phase 1: Creating directory structure...');
|
|
36
|
+
await createDirectoryStructure();
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
38
|
+
// Phase 2: Create base configuration
|
|
39
|
+
console.log('\nāļø Phase 2: Creating configuration...');
|
|
40
|
+
await createClaudeConfig(options);
|
|
32
41
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
// Phase 3: Create swarm commands and documentation
|
|
43
|
+
console.log('\nš¤ Phase 3: Creating swarm commands...');
|
|
44
|
+
await createSwarmCommands();
|
|
36
45
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
|
|
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> {
|