foliko 2.0.4 → 2.0.5
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/.editorconfig +56 -56
- package/.lintstagedrc +7 -7
- package/.prettierignore +29 -29
- package/.prettierrc +11 -11
- package/Dockerfile +63 -63
- package/docs/public-api.md +924 -6
- package/install.ps1 +129 -129
- package/install.sh +121 -121
- package/package.json +1 -1
- package/plugins/core/default/bootstrap.js +21 -0
- package/plugins/core/skill-manager/index.js +158 -0
- package/plugins/core/workflow/index.js +24 -0
- package/skills/find-skills/SKILL.md +133 -133
- package/src/agent/prompt-registry.js +95 -89
- package/src/framework/framework.js +616 -2
- package/src/plugin/base.js +5 -5
- package/tests/core/plugin-prompts.test.js +13 -13
- package/tests/core/prompt-registry.test.js +59 -51
package/install.ps1
CHANGED
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
# Foliko Installer
|
|
2
|
-
|
|
3
|
-
# Fix execution policy first
|
|
4
|
-
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force -ErrorAction SilentlyContinue
|
|
5
|
-
|
|
6
|
-
Write-Host "Foliko Installer"
|
|
7
|
-
Write-Host "================="
|
|
8
|
-
Write-Host ""
|
|
9
|
-
|
|
10
|
-
# Refresh PATH
|
|
11
|
-
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
12
|
-
|
|
13
|
-
# ============ Check/Install Node.js ============
|
|
14
|
-
Write-Host "Checking Node.js..."
|
|
15
|
-
if (Get-Command node -ErrorAction SilentlyContinue) {
|
|
16
|
-
Write-Host "Node.js installed: $(node --version)" -ForegroundColor Green
|
|
17
|
-
} else {
|
|
18
|
-
Write-Host "Node.js not found, installing..." -ForegroundColor Yellow
|
|
19
|
-
|
|
20
|
-
$nodeUrl = "https://nodejs.org/dist/v20.11.0/node-v20.11.0-x64.msi"
|
|
21
|
-
$nodeInstaller = "$env:TEMP\node-installer.msi"
|
|
22
|
-
|
|
23
|
-
Write-Host "Downloading Node.js..." -ForegroundColor Cyan
|
|
24
|
-
Invoke-WebRequest -Uri $nodeUrl -OutFile $nodeInstaller -UseBasicParsing
|
|
25
|
-
|
|
26
|
-
Write-Host "Installing Node.js (may require admin)..." -ForegroundColor Cyan
|
|
27
|
-
Start-Process msiexec.exe -ArgumentList "/i", $nodeInstaller, "/quiet", "/norestart" -Wait
|
|
28
|
-
|
|
29
|
-
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
30
|
-
Start-Sleep -Seconds 3
|
|
31
|
-
|
|
32
|
-
if (Get-Command node -ErrorAction SilentlyContinue) {
|
|
33
|
-
Write-Host "Node.js installed: $(node --version)" -ForegroundColor Green
|
|
34
|
-
Remove-Item $nodeInstaller -Force -ErrorAction SilentlyContinue
|
|
35
|
-
} else {
|
|
36
|
-
Write-Host "Node.js installation failed" -ForegroundColor Red
|
|
37
|
-
Write-Host "Download manually: https://nodejs.org/" -ForegroundColor Yellow
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
Write-Host ""
|
|
41
|
-
|
|
42
|
-
# ============ Check/Install Python ============
|
|
43
|
-
Write-Host "Checking Python..."
|
|
44
|
-
if (Get-Command python -ErrorAction SilentlyContinue) {
|
|
45
|
-
Write-Host "Python installed: $(python --version)" -ForegroundColor Green
|
|
46
|
-
} else {
|
|
47
|
-
Write-Host "Python not found, installing..." -ForegroundColor Yellow
|
|
48
|
-
|
|
49
|
-
$pythonUrl = "https://www.python.org/ftp/python/3.12.1/python-3.12.1-amd64.exe"
|
|
50
|
-
$pythonInstaller = "$env:TEMP\python-installer.exe"
|
|
51
|
-
|
|
52
|
-
Write-Host "Downloading Python..." -ForegroundColor Cyan
|
|
53
|
-
Invoke-WebRequest -Uri $pythonUrl -OutFile $pythonInstaller -UseBasicParsing
|
|
54
|
-
|
|
55
|
-
Write-Host "Installing Python (may require admin)..." -ForegroundColor Cyan
|
|
56
|
-
Start-Process $pythonInstaller -ArgumentList "/quiet", "InstallAllUsers=1", "PrependPath=1", "Include_pip=1" -Wait
|
|
57
|
-
|
|
58
|
-
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
59
|
-
Start-Sleep -Seconds 3
|
|
60
|
-
|
|
61
|
-
if (Get-Command python -ErrorAction SilentlyContinue) {
|
|
62
|
-
Write-Host "Python installed: $(python --version)" -ForegroundColor Green
|
|
63
|
-
Remove-Item $pythonInstaller -Force -ErrorAction SilentlyContinue
|
|
64
|
-
} else {
|
|
65
|
-
Write-Host "Python installation failed" -ForegroundColor Red
|
|
66
|
-
Write-Host "Download manually: https://www.python.org/downloads/" -ForegroundColor Yellow
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
Write-Host ""
|
|
70
|
-
|
|
71
|
-
# ============ Check/Install uv ============
|
|
72
|
-
Write-Host "Checking uv..."
|
|
73
|
-
if (Get-Command uv -ErrorAction SilentlyContinue) {
|
|
74
|
-
Write-Host "uv installed: $(uv --version)" -ForegroundColor Green
|
|
75
|
-
} else {
|
|
76
|
-
Write-Host "uv not found, installing..." -ForegroundColor Yellow
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
Write-Host "Downloading uv..." -ForegroundColor Cyan
|
|
80
|
-
Invoke-WebRequest -Uri "https://astral.sh/uv/install.ps1" -OutFile "$env:TEMP\install-uv.ps1" -UseBasicParsing
|
|
81
|
-
powershell -ExecutionPolicy Bypass -File "$env:TEMP\install-uv.ps1" -Version "0.4.0" -PowerShell -Admin
|
|
82
|
-
Remove-Item "$env:TEMP\install-uv.ps1" -Force -ErrorAction SilentlyContinue
|
|
83
|
-
|
|
84
|
-
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
85
|
-
|
|
86
|
-
if (Get-Command uv -ErrorAction SilentlyContinue) {
|
|
87
|
-
Write-Host "uv installed: $(uv --version)" -ForegroundColor Green
|
|
88
|
-
}
|
|
89
|
-
} catch {
|
|
90
|
-
Write-Host "uv installation failed (optional, can be skipped)" -ForegroundColor Yellow
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
Write-Host ""
|
|
94
|
-
|
|
95
|
-
# ============ Clean npm cache and install Foliko ============
|
|
96
|
-
Write-Host "Cleaning npm cache..." -ForegroundColor Cyan
|
|
97
|
-
npm cache clean --force 2>$null | Out-Null
|
|
98
|
-
|
|
99
|
-
Write-Host "Installing Foliko..." -ForegroundColor Cyan
|
|
100
|
-
npm install -g foliko --ignore-scripts 2>&1 | Out-Null
|
|
101
|
-
|
|
102
|
-
# Get npm global bin path
|
|
103
|
-
$npmPrefix = npm config get prefix 2>$null
|
|
104
|
-
$npmBinPath = $npmPrefix -replace "\\$", ""
|
|
105
|
-
|
|
106
|
-
# Add to PATH permanently for current user
|
|
107
|
-
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
108
|
-
if ($userPath -notlike "*$npmBinPath*") {
|
|
109
|
-
[Environment]::SetEnvironmentVariable("Path", "$userPath;$npmBinPath", "User")
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
# Also add to current session PATH
|
|
113
|
-
$env:Path = "$npmBinPath;$env:Path"
|
|
114
|
-
Start-Sleep -Seconds 2
|
|
115
|
-
|
|
116
|
-
# Check if installation succeeded
|
|
117
|
-
if (Test-Path "$npmBinPath\foliko.cmd") {
|
|
118
|
-
Write-Host ""
|
|
119
|
-
Write-Host "Installation complete!" -ForegroundColor Green
|
|
120
|
-
Write-Host ""
|
|
121
|
-
Write-Host "Please restart your terminal or run:" -ForegroundColor Cyan
|
|
122
|
-
Write-Host ' $env:Path = "C:\Users\Administrator\AppData\Roaming\npm;' + '$env:Path"' -ForegroundColor White
|
|
123
|
-
Write-Host ""
|
|
124
|
-
Write-Host "Then run: foliko chat" -ForegroundColor Yellow
|
|
125
|
-
} else {
|
|
126
|
-
Write-Host ""
|
|
127
|
-
Write-Host "Installation may have failed." -ForegroundColor Yellow
|
|
128
|
-
Write-Host "Run: npm install -g foliko"
|
|
129
|
-
}
|
|
1
|
+
# Foliko Installer
|
|
2
|
+
|
|
3
|
+
# Fix execution policy first
|
|
4
|
+
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force -ErrorAction SilentlyContinue
|
|
5
|
+
|
|
6
|
+
Write-Host "Foliko Installer"
|
|
7
|
+
Write-Host "================="
|
|
8
|
+
Write-Host ""
|
|
9
|
+
|
|
10
|
+
# Refresh PATH
|
|
11
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
12
|
+
|
|
13
|
+
# ============ Check/Install Node.js ============
|
|
14
|
+
Write-Host "Checking Node.js..."
|
|
15
|
+
if (Get-Command node -ErrorAction SilentlyContinue) {
|
|
16
|
+
Write-Host "Node.js installed: $(node --version)" -ForegroundColor Green
|
|
17
|
+
} else {
|
|
18
|
+
Write-Host "Node.js not found, installing..." -ForegroundColor Yellow
|
|
19
|
+
|
|
20
|
+
$nodeUrl = "https://nodejs.org/dist/v20.11.0/node-v20.11.0-x64.msi"
|
|
21
|
+
$nodeInstaller = "$env:TEMP\node-installer.msi"
|
|
22
|
+
|
|
23
|
+
Write-Host "Downloading Node.js..." -ForegroundColor Cyan
|
|
24
|
+
Invoke-WebRequest -Uri $nodeUrl -OutFile $nodeInstaller -UseBasicParsing
|
|
25
|
+
|
|
26
|
+
Write-Host "Installing Node.js (may require admin)..." -ForegroundColor Cyan
|
|
27
|
+
Start-Process msiexec.exe -ArgumentList "/i", $nodeInstaller, "/quiet", "/norestart" -Wait
|
|
28
|
+
|
|
29
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
30
|
+
Start-Sleep -Seconds 3
|
|
31
|
+
|
|
32
|
+
if (Get-Command node -ErrorAction SilentlyContinue) {
|
|
33
|
+
Write-Host "Node.js installed: $(node --version)" -ForegroundColor Green
|
|
34
|
+
Remove-Item $nodeInstaller -Force -ErrorAction SilentlyContinue
|
|
35
|
+
} else {
|
|
36
|
+
Write-Host "Node.js installation failed" -ForegroundColor Red
|
|
37
|
+
Write-Host "Download manually: https://nodejs.org/" -ForegroundColor Yellow
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
Write-Host ""
|
|
41
|
+
|
|
42
|
+
# ============ Check/Install Python ============
|
|
43
|
+
Write-Host "Checking Python..."
|
|
44
|
+
if (Get-Command python -ErrorAction SilentlyContinue) {
|
|
45
|
+
Write-Host "Python installed: $(python --version)" -ForegroundColor Green
|
|
46
|
+
} else {
|
|
47
|
+
Write-Host "Python not found, installing..." -ForegroundColor Yellow
|
|
48
|
+
|
|
49
|
+
$pythonUrl = "https://www.python.org/ftp/python/3.12.1/python-3.12.1-amd64.exe"
|
|
50
|
+
$pythonInstaller = "$env:TEMP\python-installer.exe"
|
|
51
|
+
|
|
52
|
+
Write-Host "Downloading Python..." -ForegroundColor Cyan
|
|
53
|
+
Invoke-WebRequest -Uri $pythonUrl -OutFile $pythonInstaller -UseBasicParsing
|
|
54
|
+
|
|
55
|
+
Write-Host "Installing Python (may require admin)..." -ForegroundColor Cyan
|
|
56
|
+
Start-Process $pythonInstaller -ArgumentList "/quiet", "InstallAllUsers=1", "PrependPath=1", "Include_pip=1" -Wait
|
|
57
|
+
|
|
58
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
59
|
+
Start-Sleep -Seconds 3
|
|
60
|
+
|
|
61
|
+
if (Get-Command python -ErrorAction SilentlyContinue) {
|
|
62
|
+
Write-Host "Python installed: $(python --version)" -ForegroundColor Green
|
|
63
|
+
Remove-Item $pythonInstaller -Force -ErrorAction SilentlyContinue
|
|
64
|
+
} else {
|
|
65
|
+
Write-Host "Python installation failed" -ForegroundColor Red
|
|
66
|
+
Write-Host "Download manually: https://www.python.org/downloads/" -ForegroundColor Yellow
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
Write-Host ""
|
|
70
|
+
|
|
71
|
+
# ============ Check/Install uv ============
|
|
72
|
+
Write-Host "Checking uv..."
|
|
73
|
+
if (Get-Command uv -ErrorAction SilentlyContinue) {
|
|
74
|
+
Write-Host "uv installed: $(uv --version)" -ForegroundColor Green
|
|
75
|
+
} else {
|
|
76
|
+
Write-Host "uv not found, installing..." -ForegroundColor Yellow
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
Write-Host "Downloading uv..." -ForegroundColor Cyan
|
|
80
|
+
Invoke-WebRequest -Uri "https://astral.sh/uv/install.ps1" -OutFile "$env:TEMP\install-uv.ps1" -UseBasicParsing
|
|
81
|
+
powershell -ExecutionPolicy Bypass -File "$env:TEMP\install-uv.ps1" -Version "0.4.0" -PowerShell -Admin
|
|
82
|
+
Remove-Item "$env:TEMP\install-uv.ps1" -Force -ErrorAction SilentlyContinue
|
|
83
|
+
|
|
84
|
+
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
85
|
+
|
|
86
|
+
if (Get-Command uv -ErrorAction SilentlyContinue) {
|
|
87
|
+
Write-Host "uv installed: $(uv --version)" -ForegroundColor Green
|
|
88
|
+
}
|
|
89
|
+
} catch {
|
|
90
|
+
Write-Host "uv installation failed (optional, can be skipped)" -ForegroundColor Yellow
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
Write-Host ""
|
|
94
|
+
|
|
95
|
+
# ============ Clean npm cache and install Foliko ============
|
|
96
|
+
Write-Host "Cleaning npm cache..." -ForegroundColor Cyan
|
|
97
|
+
npm cache clean --force 2>$null | Out-Null
|
|
98
|
+
|
|
99
|
+
Write-Host "Installing Foliko..." -ForegroundColor Cyan
|
|
100
|
+
npm install -g foliko --ignore-scripts 2>&1 | Out-Null
|
|
101
|
+
|
|
102
|
+
# Get npm global bin path
|
|
103
|
+
$npmPrefix = npm config get prefix 2>$null
|
|
104
|
+
$npmBinPath = $npmPrefix -replace "\\$", ""
|
|
105
|
+
|
|
106
|
+
# Add to PATH permanently for current user
|
|
107
|
+
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
108
|
+
if ($userPath -notlike "*$npmBinPath*") {
|
|
109
|
+
[Environment]::SetEnvironmentVariable("Path", "$userPath;$npmBinPath", "User")
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# Also add to current session PATH
|
|
113
|
+
$env:Path = "$npmBinPath;$env:Path"
|
|
114
|
+
Start-Sleep -Seconds 2
|
|
115
|
+
|
|
116
|
+
# Check if installation succeeded
|
|
117
|
+
if (Test-Path "$npmBinPath\foliko.cmd") {
|
|
118
|
+
Write-Host ""
|
|
119
|
+
Write-Host "Installation complete!" -ForegroundColor Green
|
|
120
|
+
Write-Host ""
|
|
121
|
+
Write-Host "Please restart your terminal or run:" -ForegroundColor Cyan
|
|
122
|
+
Write-Host ' $env:Path = "C:\Users\Administrator\AppData\Roaming\npm;' + '$env:Path"' -ForegroundColor White
|
|
123
|
+
Write-Host ""
|
|
124
|
+
Write-Host "Then run: foliko chat" -ForegroundColor Yellow
|
|
125
|
+
} else {
|
|
126
|
+
Write-Host ""
|
|
127
|
+
Write-Host "Installation may have failed." -ForegroundColor Yellow
|
|
128
|
+
Write-Host "Run: npm install -g foliko"
|
|
129
|
+
}
|
package/install.sh
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Foliko Installer
|
|
3
|
-
|
|
4
|
-
set -e
|
|
5
|
-
|
|
6
|
-
echo -e "\033[36mFoliko Installer\033[0m"
|
|
7
|
-
echo -e "\033[36m=================\033[0m"
|
|
8
|
-
echo ""
|
|
9
|
-
|
|
10
|
-
# Detect OS
|
|
11
|
-
detect_os() {
|
|
12
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
13
|
-
echo "macOS"
|
|
14
|
-
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
15
|
-
echo "Linux"
|
|
16
|
-
else
|
|
17
|
-
echo "unknown"
|
|
18
|
-
fi
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
OS=$(detect_os)
|
|
22
|
-
|
|
23
|
-
# ============ Check/Install Node.js ============
|
|
24
|
-
echo -e "\033[36mChecking Node.js...\033[0m"
|
|
25
|
-
if command -v node &> /dev/null; then
|
|
26
|
-
echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
|
|
27
|
-
else
|
|
28
|
-
echo -e "\033[33mNode.js not found, installing...\033[0m"
|
|
29
|
-
|
|
30
|
-
if [[ "$OS" == "macOS" ]]; then
|
|
31
|
-
if command -v brew &> /dev/null; then
|
|
32
|
-
brew install node
|
|
33
|
-
else
|
|
34
|
-
echo -e "\033[31mHomebrew not found. Install it first:\033[0m"
|
|
35
|
-
echo "/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
|
36
|
-
exit 1
|
|
37
|
-
fi
|
|
38
|
-
elif [[ "$OS" == "Linux" ]]; then
|
|
39
|
-
if command -v apt-get &> /dev/null; then
|
|
40
|
-
sudo apt-get update && sudo apt-get install -y nodejs npm
|
|
41
|
-
elif command -v yum &> /dev/null; then
|
|
42
|
-
sudo yum install -y nodejs npm
|
|
43
|
-
elif command -v pacman &> /dev/null; then
|
|
44
|
-
sudo pacman -S nodejs npm
|
|
45
|
-
else
|
|
46
|
-
echo -e "\033[31mNo package manager found. Install Node.js manually: https://nodejs.org/\033[0m"
|
|
47
|
-
exit 1
|
|
48
|
-
fi
|
|
49
|
-
fi
|
|
50
|
-
|
|
51
|
-
if command -v node &> /dev/null; then
|
|
52
|
-
echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
|
|
53
|
-
else
|
|
54
|
-
echo -e "\033[31mNode.js installation failed\033[0m"
|
|
55
|
-
exit 1
|
|
56
|
-
fi
|
|
57
|
-
fi
|
|
58
|
-
echo ""
|
|
59
|
-
|
|
60
|
-
# ============ Check/Install Python ============
|
|
61
|
-
echo -e "\033[36mChecking Python...\033[0m"
|
|
62
|
-
if command -v python3 &> /dev/null; then
|
|
63
|
-
echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
|
|
64
|
-
else
|
|
65
|
-
echo -e "\033[33mPython not found, installing...\033[0m"
|
|
66
|
-
|
|
67
|
-
if [[ "$OS" == "macOS" ]]; then
|
|
68
|
-
if command -v brew &> /dev/null; then
|
|
69
|
-
brew install python3
|
|
70
|
-
fi
|
|
71
|
-
elif [[ "$OS" == "Linux" ]]; then
|
|
72
|
-
if command -v apt-get &> /dev/null; then
|
|
73
|
-
sudo apt-get update && sudo apt-get install -y python3 python3-venv python3-pip
|
|
74
|
-
elif command -v yum &> /dev/null; then
|
|
75
|
-
sudo yum install -y python3
|
|
76
|
-
elif command -v pacman &> /dev/null; then
|
|
77
|
-
sudo pacman -S python python-pip
|
|
78
|
-
fi
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
if command -v python3 &> /dev/null; then
|
|
82
|
-
echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
|
|
83
|
-
else
|
|
84
|
-
echo -e "\033[33mPython installation failed (optional)\033[0m"
|
|
85
|
-
fi
|
|
86
|
-
fi
|
|
87
|
-
echo ""
|
|
88
|
-
|
|
89
|
-
# ============ Check/Install uv ============
|
|
90
|
-
echo -e "\033[36mChecking uv...\033[0m"
|
|
91
|
-
if command -v uv &> /dev/null; then
|
|
92
|
-
echo -e "\033[32muv installed: $(uv --version)\033[0m"
|
|
93
|
-
else
|
|
94
|
-
echo -e "\033[33muv not found, installing...\033[0m"
|
|
95
|
-
|
|
96
|
-
if [[ "$OS" == "macOS" ]] || [[ "$OS" == "Linux" ]]; then
|
|
97
|
-
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
98
|
-
source $HOME/.local/bin/env 2>/dev/null || true
|
|
99
|
-
|
|
100
|
-
if command -v uv &> /dev/null; then
|
|
101
|
-
echo -e "\033[32muv installed: $(uv --version)\033[0m"
|
|
102
|
-
else
|
|
103
|
-
echo -e "\033[33muv installation failed (optional)\033[0m"
|
|
104
|
-
fi
|
|
105
|
-
fi
|
|
106
|
-
fi
|
|
107
|
-
echo ""
|
|
108
|
-
|
|
109
|
-
# ============ Install Foliko ============
|
|
110
|
-
echo -e "\033[36mInstalling Foliko...\033[0m"
|
|
111
|
-
npm install -g foliko
|
|
112
|
-
|
|
113
|
-
if command -v foliko &> /dev/null; then
|
|
114
|
-
echo ""
|
|
115
|
-
echo -e "\033[32mInstallation complete!\033[0m"
|
|
116
|
-
echo "Run: foliko chat"
|
|
117
|
-
else
|
|
118
|
-
echo ""
|
|
119
|
-
echo -e "\033[31mInstallation failed. Try manually: npm install -g foliko\033[0m"
|
|
120
|
-
exit 1
|
|
121
|
-
fi
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Foliko Installer
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
echo -e "\033[36mFoliko Installer\033[0m"
|
|
7
|
+
echo -e "\033[36m=================\033[0m"
|
|
8
|
+
echo ""
|
|
9
|
+
|
|
10
|
+
# Detect OS
|
|
11
|
+
detect_os() {
|
|
12
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
13
|
+
echo "macOS"
|
|
14
|
+
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
15
|
+
echo "Linux"
|
|
16
|
+
else
|
|
17
|
+
echo "unknown"
|
|
18
|
+
fi
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
OS=$(detect_os)
|
|
22
|
+
|
|
23
|
+
# ============ Check/Install Node.js ============
|
|
24
|
+
echo -e "\033[36mChecking Node.js...\033[0m"
|
|
25
|
+
if command -v node &> /dev/null; then
|
|
26
|
+
echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
|
|
27
|
+
else
|
|
28
|
+
echo -e "\033[33mNode.js not found, installing...\033[0m"
|
|
29
|
+
|
|
30
|
+
if [[ "$OS" == "macOS" ]]; then
|
|
31
|
+
if command -v brew &> /dev/null; then
|
|
32
|
+
brew install node
|
|
33
|
+
else
|
|
34
|
+
echo -e "\033[31mHomebrew not found. Install it first:\033[0m"
|
|
35
|
+
echo "/bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
elif [[ "$OS" == "Linux" ]]; then
|
|
39
|
+
if command -v apt-get &> /dev/null; then
|
|
40
|
+
sudo apt-get update && sudo apt-get install -y nodejs npm
|
|
41
|
+
elif command -v yum &> /dev/null; then
|
|
42
|
+
sudo yum install -y nodejs npm
|
|
43
|
+
elif command -v pacman &> /dev/null; then
|
|
44
|
+
sudo pacman -S nodejs npm
|
|
45
|
+
else
|
|
46
|
+
echo -e "\033[31mNo package manager found. Install Node.js manually: https://nodejs.org/\033[0m"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if command -v node &> /dev/null; then
|
|
52
|
+
echo -e "\033[32mNode.js installed: $(node --version)\033[0m"
|
|
53
|
+
else
|
|
54
|
+
echo -e "\033[31mNode.js installation failed\033[0m"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
echo ""
|
|
59
|
+
|
|
60
|
+
# ============ Check/Install Python ============
|
|
61
|
+
echo -e "\033[36mChecking Python...\033[0m"
|
|
62
|
+
if command -v python3 &> /dev/null; then
|
|
63
|
+
echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
|
|
64
|
+
else
|
|
65
|
+
echo -e "\033[33mPython not found, installing...\033[0m"
|
|
66
|
+
|
|
67
|
+
if [[ "$OS" == "macOS" ]]; then
|
|
68
|
+
if command -v brew &> /dev/null; then
|
|
69
|
+
brew install python3
|
|
70
|
+
fi
|
|
71
|
+
elif [[ "$OS" == "Linux" ]]; then
|
|
72
|
+
if command -v apt-get &> /dev/null; then
|
|
73
|
+
sudo apt-get update && sudo apt-get install -y python3 python3-venv python3-pip
|
|
74
|
+
elif command -v yum &> /dev/null; then
|
|
75
|
+
sudo yum install -y python3
|
|
76
|
+
elif command -v pacman &> /dev/null; then
|
|
77
|
+
sudo pacman -S python python-pip
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
if command -v python3 &> /dev/null; then
|
|
82
|
+
echo -e "\033[32mPython installed: $(python3 --version)\033[0m"
|
|
83
|
+
else
|
|
84
|
+
echo -e "\033[33mPython installation failed (optional)\033[0m"
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
87
|
+
echo ""
|
|
88
|
+
|
|
89
|
+
# ============ Check/Install uv ============
|
|
90
|
+
echo -e "\033[36mChecking uv...\033[0m"
|
|
91
|
+
if command -v uv &> /dev/null; then
|
|
92
|
+
echo -e "\033[32muv installed: $(uv --version)\033[0m"
|
|
93
|
+
else
|
|
94
|
+
echo -e "\033[33muv not found, installing...\033[0m"
|
|
95
|
+
|
|
96
|
+
if [[ "$OS" == "macOS" ]] || [[ "$OS" == "Linux" ]]; then
|
|
97
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
98
|
+
source $HOME/.local/bin/env 2>/dev/null || true
|
|
99
|
+
|
|
100
|
+
if command -v uv &> /dev/null; then
|
|
101
|
+
echo -e "\033[32muv installed: $(uv --version)\033[0m"
|
|
102
|
+
else
|
|
103
|
+
echo -e "\033[33muv installation failed (optional)\033[0m"
|
|
104
|
+
fi
|
|
105
|
+
fi
|
|
106
|
+
fi
|
|
107
|
+
echo ""
|
|
108
|
+
|
|
109
|
+
# ============ Install Foliko ============
|
|
110
|
+
echo -e "\033[36mInstalling Foliko...\033[0m"
|
|
111
|
+
npm install -g foliko
|
|
112
|
+
|
|
113
|
+
if command -v foliko &> /dev/null; then
|
|
114
|
+
echo ""
|
|
115
|
+
echo -e "\033[32mInstallation complete!\033[0m"
|
|
116
|
+
echo "Run: foliko chat"
|
|
117
|
+
else
|
|
118
|
+
echo ""
|
|
119
|
+
echo -e "\033[31mInstallation failed. Try manually: npm install -g foliko\033[0m"
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
package/package.json
CHANGED
|
@@ -40,15 +40,36 @@ async function loadCustomPlugins(framework, agentConfig) {
|
|
|
40
40
|
delete require.cache[require.resolve(resolved.path)];
|
|
41
41
|
const mod = require(resolved.path);
|
|
42
42
|
let pluginClass = mod.default || mod;
|
|
43
|
+
|
|
44
|
+
// 如果默认导出不是 Plugin 子类,查找模块中的 Plugin 子类
|
|
43
45
|
if (typeof pluginClass === 'function' && !(pluginClass.prototype instanceof Plugin)) {
|
|
44
46
|
const keys = Object.keys(mod).filter(k => mod[k] && mod[k].prototype instanceof Plugin);
|
|
45
47
|
if (keys.length > 0) pluginClass = mod[keys[0]];
|
|
46
48
|
}
|
|
49
|
+
|
|
50
|
+
// 如果 pluginClass 是对象(模块直接导出对象而非类),查找其中的 Plugin 子类
|
|
51
|
+
if (typeof pluginClass !== 'function' && pluginClass.prototype === undefined) {
|
|
52
|
+
const keys = Object.keys(mod).filter(k => mod[k] && mod[k].prototype instanceof Plugin);
|
|
53
|
+
if (keys.length > 0) pluginClass = mod[keys[0]];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 检查 pluginClass 是否是 Plugin 实例
|
|
57
|
+
if (pluginClass instanceof Plugin) {
|
|
58
|
+
pluginClass = pluginClass.constructor;
|
|
59
|
+
}
|
|
60
|
+
|
|
47
61
|
let resolvedName = pluginName;
|
|
48
62
|
if (typeof pluginClass === 'function' && pluginClass.prototype instanceof Plugin) {
|
|
49
63
|
resolvedName = new pluginClass().name || pluginName;
|
|
50
64
|
}
|
|
51
65
|
if (framework.pluginManager.has(resolvedName) && framework.pluginManager.get(resolvedName)?._started) continue;
|
|
66
|
+
|
|
67
|
+
// 跳过无法识别的模块(不是 Plugin 类也不是 Plugin 实例)
|
|
68
|
+
if (typeof pluginClass !== 'function' && !(pluginClass instanceof Plugin)) {
|
|
69
|
+
log.debug(`Skipping ${pluginName}: not a Plugin class or instance`);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
|
|
52
73
|
const pluginConfig = agentConfig[resolvedName] || {};
|
|
53
74
|
let instance;
|
|
54
75
|
if (typeof pluginClass === 'function') {
|