foliko 2.0.7 → 2.0.8
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/.claude/settings.local.json +2 -1
- 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 +3 -3
- package/examples/workflow.js +62 -57
- package/install.ps1 +129 -129
- package/install.sh +121 -121
- package/package.json +2 -3
- package/plugins/core/scheduler/CHANGELOG.md +31 -0
- package/plugins/core/scheduler/index.js +576 -639
- package/plugins/core/workflow/context.js +941 -941
- package/plugins/core/workflow/engine.js +66 -66
- package/plugins/core/workflow/index.js +2 -2
- package/plugins/core/workflow/js-runner.js +318 -318
- package/plugins/core/workflow/json-runner.js +323 -323
- package/plugins/core/workflow/stages/choice.js +74 -74
- package/plugins/core/workflow/stages/each.js +123 -123
- package/plugins/core/workflow/stages/parallel.js +69 -69
- package/plugins/memory/index.js +10 -3
- package/skills/find-skills/SKILL.md +133 -133
- package/src/framework/framework.js +3 -1
- package/src/index.js +10 -0
- package/src/plugin/base.js +7 -4
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "foliko",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "简约的插件化 Agent 框架",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -67,6 +67,7 @@
|
|
|
67
67
|
"ai": "^6.0.146",
|
|
68
68
|
"chalk": "^5.6.2",
|
|
69
69
|
"cli-highlight": "^2.1.11",
|
|
70
|
+
"croner": "^9.1.0",
|
|
70
71
|
"crypto": "^1.0.1",
|
|
71
72
|
"diff": "^9.0.0",
|
|
72
73
|
"dotenv": "^17.3.1",
|
|
@@ -79,9 +80,7 @@
|
|
|
79
80
|
"mailparser": "^3.7.2",
|
|
80
81
|
"marked": "^11.2.0",
|
|
81
82
|
"marked-terminal": "6",
|
|
82
|
-
"node-cron": "^4.2.1",
|
|
83
83
|
"node-html-markdown": "^1.3.0",
|
|
84
|
-
"node-schedule": "^2.1.1",
|
|
85
84
|
"node-telegram-bot-api": "^0.67.0",
|
|
86
85
|
"nodemailer": "^6.10.0",
|
|
87
86
|
"pino": "7",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
- **依赖替换**:移除 `node-schedule` 和未使用的 `node-cron`;改用 [`croner`](https://github.com/Hexagon/croner) 作为唯一调度引擎
|
|
8
|
+
- 用户配置(`schedule_task` 工具入参)完全兼容,无需改动
|
|
9
|
+
- **持久化文件 schema 微调**:`tasks.json` 新增 `timezone` 字段;旧的 `cronTask` / `timer` 字段不再写盘(之前存的是非序列化对象,无意义)
|
|
10
|
+
- 旧版 `tasks.json` 可被新代码读取(多余字段被忽略),无需手动迁移
|
|
11
|
+
- **删除内部 API**:`_taskStats`、`_checkTasks`、`_startScheduler` 整段不再存在(之前是 no-op 或死代码)
|
|
12
|
+
|
|
13
|
+
### 行为变更
|
|
14
|
+
|
|
15
|
+
- **事件循环阻塞自愈**:`croner` 用绝对时间戳校验触发时间。即使主线程被 LLM 流式响应 / 磁盘 IO 阻塞几十秒,进程恢复后**会自动 catch-up 错过的触发**(`catch: true`)
|
|
16
|
+
- **过期一次性任务补触发**:进程重启后,若一次性任务本应触发的时间点已过但在 24h 容忍期内,**立即补触发一次**;超过 24h 则丢弃并 warn
|
|
17
|
+
- **cron 任务重叠保护**:若上次任务尚未执行完(`protect: true`),下一次触发被跳过,避免并发
|
|
18
|
+
- **持久化原子化**:`saveTasks` 改为先写 `.tmp` 再 `rename`,崩溃中途不会留下半残 JSON
|
|
19
|
+
- **持久化 debounce**:500ms 内的多次 mutation 合并成一次写盘,减少 IO
|
|
20
|
+
|
|
21
|
+
### 新增
|
|
22
|
+
|
|
23
|
+
- `timezone` 配置项(默认 `Asia/Shanghai`,可通过 `config.timezone` 或环境变量 `TZ` 覆盖)
|
|
24
|
+
- `unref: true` 调度器不阻塞进程退出(避免 CLI 关闭后定时任务不退出)
|
|
25
|
+
- `schedule_list` 工具输出新增 `nextRun`(croner 的 `nextRun()` getter)和 `timezone` 字段
|
|
26
|
+
|
|
27
|
+
### 修复
|
|
28
|
+
|
|
29
|
+
- 每次 LLM 模式 cron tick 都会 `createSubAgent`,长期运行会漏内存。现在 `_schedulerSubAgent` 单例复用
|
|
30
|
+
- shell / 普通 任务的重复代码路径已合并,统一通过 `_executeTask` 分发
|
|
31
|
+
- 调度失败时不再静默 warn(`croner` 是硬依赖,启动时 require 失败直接抛)
|