foliko 2.0.5 → 2.0.6

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.
Files changed (65) hide show
  1. package/.claude/settings.local.json +4 -1
  2. package/.cli_default_systemPrompt.md +291 -0
  3. package/.editorconfig +56 -56
  4. package/.lintstagedrc +7 -7
  5. package/.prettierignore +29 -29
  6. package/.prettierrc +11 -11
  7. package/CLAUDE.md +3 -0
  8. package/Dockerfile +63 -63
  9. package/README.md +20 -3
  10. package/docs/architecture.md +34 -2
  11. package/docs/extensions.md +199 -0
  12. package/docs/migration.md +100 -0
  13. package/docs/public-api.md +280 -24
  14. package/docs/usage.md +122 -30
  15. package/install.ps1 +129 -129
  16. package/install.sh +121 -121
  17. package/package.json +1 -1
  18. package/plugins/core/audit/index.js +1 -1
  19. package/plugins/core/default/bootstrap.js +44 -19
  20. package/plugins/core/python-loader/index.js +43 -25
  21. package/plugins/core/skill-manager/PROMPT.md +6 -0
  22. package/plugins/core/skill-manager/index.js +402 -115
  23. package/plugins/core/sub-agent/PROMPT.md +10 -0
  24. package/plugins/core/sub-agent/index.js +36 -3
  25. package/plugins/core/think/index.js +1 -0
  26. package/plugins/core/workflow/index.js +82 -22
  27. package/plugins/executors/data-splitter/PROMPT.md +13 -0
  28. package/plugins/executors/data-splitter/index.js +5 -4
  29. package/plugins/executors/extension/extension-registry.js +145 -0
  30. package/plugins/executors/extension/index.js +405 -437
  31. package/plugins/executors/extension/prompt-builder.js +359 -0
  32. package/plugins/executors/extension/skill-helper.js +143 -0
  33. package/plugins/messaging/feishu/index.js +5 -3
  34. package/plugins/messaging/qq/index.js +6 -4
  35. package/plugins/messaging/telegram/index.js +6 -3
  36. package/plugins/messaging/weixin/index.js +5 -3
  37. package/plugins/tools/PROMPT.md +26 -0
  38. package/plugins/tools/index.js +6 -5
  39. package/skills/find-skills/SKILL.md +133 -133
  40. package/skills/foliko/AGENTS.md +196 -43
  41. package/skills/foliko/SKILL.md +157 -28
  42. package/skills/mcp/SKILL.md +77 -118
  43. package/skills/plugins/SKILL.md +89 -3
  44. package/skills/python/SKILL.md +57 -39
  45. package/skills/skill-guide/SKILL.md +42 -34
  46. package/skills/workflows/SKILL.md +224 -9
  47. package/skills/workflows/workflow-troubleshooting/SKILL.md +221 -281
  48. package/src/agent/chat.js +48 -27
  49. package/src/agent/main.js +34 -13
  50. package/src/agent/prompt-registry.js +56 -16
  51. package/src/agent/prompts/PROMPT.md +3 -0
  52. package/src/agent/sub.js +1 -1
  53. package/src/cli/ui/chat-ui-old.js +5 -2
  54. package/src/cli/ui/chat-ui.js +5 -2
  55. package/src/common/constants.js +12 -0
  56. package/src/common/error-capture.js +91 -0
  57. package/src/common/logger.js +2 -2
  58. package/src/context/compressor.js +6 -2
  59. package/src/executors/mcp-executor.js +105 -125
  60. package/src/framework/framework.js +23 -11
  61. package/src/index.js +4 -0
  62. package/src/plugin/base.js +908 -5
  63. package/src/plugin/manager.js +29 -8
  64. package/src/tool/schema.js +32 -9
  65. package/website/index.html +821 -0
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.5",
3
+ "version": "2.0.6",
4
4
  "description": "简约的插件化 Agent 框架",
5
5
  "main": "src/index.js",
6
6
  "type": "commonjs",
@@ -23,7 +23,7 @@ class AuditPlugin extends Plugin {
23
23
  this.config = {
24
24
  maxLogs: config.maxLogs || 1000,
25
25
  retentionDays: config.retentionDays || 30,
26
- logDir: config.logDir || path.join(os.homedir(), '.vb-agent', 'logs', 'audit')
26
+ logDir: config.logDir || path.join(os.homedir(), '.foliko', 'logs', 'audit')
27
27
  }
28
28
 
29
29
  this._framework = null
@@ -77,10 +77,21 @@ async function loadCustomPlugins(framework, agentConfig) {
77
77
  // 类式:new PluginClass()
78
78
  instance = new pluginClass(pluginConfig);
79
79
  } else {
80
- // function(foliko) 格式:直接调用,传入 framework
81
- pluginClass(framework);
82
- // function(foliko) 不需要 return,插件内部自己注册
83
- instance = null; // 不再作为插件实例加载
80
+ // function(Plugin) 或 function(foliko) 格式:尝试调用
81
+ try {
82
+ // 优先尝试 function(Plugin) 格式
83
+ const Result = pluginClass(Plugin);
84
+ if (Result && Result.prototype instanceof Plugin) {
85
+ instance = new Result(pluginConfig);
86
+ } else {
87
+ // function(foliko) 格式:传入 framework
88
+ pluginClass(framework);
89
+ instance = null;
90
+ }
91
+ } catch (err) {
92
+ log.error(`Failed to call plugin factory ${pluginName}:`, err.message);
93
+ continue;
94
+ }
84
95
  }
85
96
  } else {
86
97
  instance = pluginClass;
@@ -148,21 +159,6 @@ async function bootstrapDefaults(framework, config = {}) {
148
159
  }));
149
160
  }
150
161
 
151
- // 1.5 Main Agent
152
- if (!framework._mainAgent) {
153
- const { Agent } = require('../../../src/agent/main');
154
- const aiPlugin = framework.pluginManager.get('ai');
155
- framework._mainAgent = framework.createAgent({
156
- name: 'MainAgent',
157
- systemPrompt: '你是一个智能助手。当用户提出问题或任务时,你会主动分析需求,选择合适的工具来获取信息或执行操作。你善于将复杂任务拆解为多个步骤,通过工具协作完成。',
158
- model: aiConfig.model || 'deepseek-chat',
159
- provider: aiConfig.provider || 'deepseek',
160
- apiKey: aiPlugin ? aiPlugin.config.apiKey : (aiConfig.apiKey || envApiKey),
161
- baseURL: aiConfig.baseURL,
162
- });
163
- framework._agents.push(framework._mainAgent);
164
- }
165
-
166
162
  // 1.875 Extension executor (needed by skill-manager for slash commands)
167
163
  if (shouldLoad('extension-executor')) {
168
164
  const ExtensionExecutorPlugin = require('../../executors/extension');
@@ -251,6 +247,35 @@ async function bootstrapDefaults(framework, config = {}) {
251
247
  // 统一启动所有插件
252
248
  await framework.pluginManager.startAll();
253
249
 
250
+ // 等待 skill-manager 完成首次异步加载 (`_loadAllSkills` 包含动态 import ESM 的 index.js)
251
+ // 否则 MainAgent 首次 _buildSystemPrompt() 会错过 skill 命令
252
+ const skillManagerEntry = framework.pluginManager.get('skill-manager');
253
+ if (skillManagerEntry && typeof skillManagerEntry._loadReady?.then === 'function') {
254
+ try {
255
+ await skillManagerEntry._loadReady;
256
+ } catch (_) { /* 加载失败已在 skill-manager 内 log */ }
257
+ }
258
+
259
+ // ============= Main Agent (在所有 plugins 加载并 start 之后) =============
260
+ // 修复: 必须放到所有 plugins 加载并 start 之后再创建,并且 await skill-manager 的
261
+ // _loadReady。
262
+ // 原顺序下 MainAgent.constructor 会立即 _buildSystemPrompt(),此时 extension-executor
263
+ // 和 skill-manager 还没注册工具到 prompt registry,导致系统提示词里看不到 skill 命令
264
+ // —— 之前用户必须 reload 一次才看到就是这个 race。
265
+ if (!framework._mainAgent) {
266
+ const { Agent } = require('../../../src/agent/main');
267
+ const aiPlugin = framework.pluginManager.get('ai');
268
+ framework._mainAgent = framework.createAgent({
269
+ name: 'MainAgent',
270
+ systemPrompt: '你是一个智能助手。当用户提出问题或任务时,你会主动分析需求,选择合适的工具来获取信息或执行操作。你善于将复杂任务拆解为多个步骤,通过工具协作完成。',
271
+ model: aiConfig.model || 'deepseek-chat',
272
+ provider: aiConfig.provider || 'deepseek',
273
+ apiKey: aiPlugin ? aiPlugin.config.apiKey : (aiConfig.apiKey || envApiKey),
274
+ baseURL: aiConfig.baseURL,
275
+ });
276
+ framework._agents.push(framework._mainAgent);
277
+ }
278
+
254
279
  // 退出 bootstrap 模式
255
280
  framework.pluginManager.setBootstrapping(false);
256
281
  }