foliko 1.0.19 → 1.0.21

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.
@@ -1,61 +1,62 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(grep -r \"dotenv\" \"D:/Code/vb-agent/\" --include=\"*.json\" 2>/dev/null | head -20)",
5
- "Bash(cd \"D:/Code/vb-agent\" && pnpm add dotenv)",
6
- "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(Object.keys\\(ai\\).filter\\(k => k.toLowerCase\\(\\).includes\\('reason'\\) || k.toLowerCase\\(\\).includes\\('split'\\) || k.toLowerCase\\(\\).includes\\('think'\\)\\)\\)\")",
7
- "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(typeof ai.extractReasoningMiddleware, ai.extractReasoningMiddleware.toString\\(\\).substring\\(0, 500\\)\\)\")",
8
- "Bash(cd \"D:/Code/vb-agent\" && node -e \"\nconst ai = require\\('ai'\\);\nconsole.log\\('=== extractReasoningMiddleware ==='\\);\nconsole.log\\(ai.extractReasoningMiddleware.toString\\(\\)\\);\nconsole.log\\('\\\\n=== isReasoningUIPart ==='\\);\nconsole.log\\(typeof ai.isReasoningUIPart\\);\n\")",
9
- "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(Object.keys\\(ai\\).filter\\(k => k.toLowerCase\\(\\).includes\\('split'\\)\\)\\)\")",
10
- "Bash(cd \"D:/Code/vb-agent\" && pnpm add ink react)",
11
- "Bash(cd \"D:/Code/vb-agent\" && node cli/bin/foliko.js --help)",
12
- "Bash(cd \"D:/Code/vb-agent\" && timeout 2 node cli/bin/foliko.js chat 2>&1 || true)",
13
- "Bash(cd \"D:/Code/vb-agent\" && node -e \"const mt = require\\('marked-terminal'\\); console.log\\(typeof mt, Object.keys\\(mt\\)\\)\")",
14
- "Bash(cd \"D:/Code/vb-agent\" && timeout 3 node cli/bin/foliko.js chat 2>&1 || true)",
15
- "Bash(echo \"你好\" | node cli/bin/foliko.js chat 2>&1 | head -50)",
16
- "Bash(printf '思考一下1+1等于几\\\\n' | node cli/bin/foliko.js chat 2>&1 | head -100)",
17
- "Bash(printf '1+1等于几\\\\n' | node cli/bin/foliko.js chat 2>&1)",
18
- "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\nconsole.log\\(renderLine\\('🎉 这是一个 emoji'\\)\\)\nconsole.log\\(renderLine\\('**粗体** 和 🎉'\\)\\)\n\")",
19
- "Bash(node -e \"\nconst { render } = require\\('./cli/src/utils/markdown'\\)\nconst text = '🎉 今天是个好日子\\\\n## 标题\\\\n- 列表项1\\\\n- 列表项2'\nconsole.log\\(render\\(text\\)\\)\n\")",
20
- "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\n\n// 模拟emoji被截断的情况\nconst emoji = '🎉'\nconsole.log\\('完整的 emoji:', renderLine\\(emoji\\)\\)\n\n// 模拟截断 - emoji的UTF-8字节是 \\\\xF0\\\\x9F\\\\x8E\\\\x89\nconst partial = '\\\\xF0\\\\x9F' // 不完整的emoji\nconsole.log\\('截断的 emoji:', renderLine\\(partial\\)\\)\n\")",
21
- "Bash(node -e \"\nconst isIncompleteUTF8 = \\(str\\) => {\n if \\(!str || str.length === 0\\) return false\n const lastChar = str.charCodeAt\\(str.length - 1\\)\n if \\(lastChar >= 0x80 && lastChar < 0xC0\\) return true\n return false\n}\n\n// 测试各种emoji\nconst tests = ['🎉', '📁', '⚡', '🛠️', '🔑', '💾', '📝', '⏰', '🔌', '📋']\ntests.forEach\\(e => {\n console.log\\(e, '完整:', !isIncompleteUTF8\\(e\\)\\)\n}\\)\n\n// 测试被截断的emoji \\(只保留第一字节\\)\nconst broken = '🎉'.slice\\(0, 1\\)\nconsole.log\\('截断emoji:', broken, '检测:', isIncompleteUTF8\\(broken\\)\\)\n\")",
22
- "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\nconsole.log\\('测试:', renderLine\\('📁 文件操作:读取、创建'\\)\\)\n\")",
23
- "Bash(node -e \"\nconst hasIncompleteSurrogate = \\(str\\) => {\n if \\(!str || str.length === 0\\) return false\n const lastChar = str.charCodeAt\\(str.length - 1\\)\n console.log\\('检查:', str, 'lastChar:', lastChar.toString\\(16\\), '范围:', \\(lastChar >= 0xD800 && lastChar <= 0xDBFF\\)\\)\n return lastChar >= 0xD800 && lastChar <= 0xDBFF\n}\n\nconst chunk1 = '\\\\xD83C'\nconsole.log\\('结果:', hasIncompleteSurrogate\\(chunk1\\)\\)\n\")",
24
- "Bash(cd D:/Code/vb-agent && node test-stream-emoji.js 2>&1)",
25
- "Read(//d/Date/20260321/app/**)",
26
- "Bash(node -e \":*)",
27
- "Bash(node -e \"\nconst { loadAgentConfig } = require\\('./plugins/default-plugins'\\);\nconst config = loadAgentConfig\\('D:/Date/20260321/app/.agent'\\);\nconsole.log\\('skillsDirs:', config.skillsDirs\\);\n\")",
28
- "Bash(cd D:/Code/vb-agent && pnpm install --shamefully-hoist 2>&1 | head -20)",
29
- "Bash(cd D:/Code/vb-agent && rm -rf node_modules && pnpm install)",
30
- "Bash(cd D:/Code/vb-agent && timeout 8 node test-tg.js 2>&1 || true)",
31
- "Bash(cd D:/Code/vb-agent && timeout 10 node test-tg.js 2>&1 || true)",
32
- "Bash(find /d/Code/vb-agent -name \"*email*\" -type f 2>/dev/null | grep -v node_modules | grep -v .git)",
33
- "Bash(find /d/Code/vb-agent -maxdepth 2 -name \"*.md\" -type f 2>/dev/null | grep -v node_modules)",
34
- "Bash(node -c plugins/default-plugins.js && node -c src/core/plugin-manager.js && echo \"Syntax OK\")",
35
- "Bash(node -c plugins/install-plugin.js && echo \"Syntax OK\")",
36
- "Bash(node -c cli/src/ui/chat-ui.js && echo \"Syntax OK\")",
37
- "Bash(node -c plugins/default-plugins.js && echo \"Syntax OK\")",
38
- "Bash(node -c plugins/scheduler-plugin.js && echo \"Syntax OK\")",
39
- "Bash(node -c plugins/telegram-plugin.js && node -c plugins/scheduler-plugin.js && echo \"Syntax OK\")",
40
- "Bash(node -c plugins/telegram-plugin.js && echo \"Syntax OK\")",
41
- "WebSearch",
42
- "Bash(npm ls:*)",
43
- "Bash(cd node_modules/@pinixai/weixin-bot && npm run build 2>&1)",
44
- "Bash(cd node_modules/@pinixai/weixin-bot && npx tsc 2>&1)",
45
- "Bash(npm install:*)",
46
- "Bash(cd node_modules/@pinixai/weixin-bot && npx typescript --version && npx tsc 2>&1)",
47
- "Bash(npx tsc:*)",
48
- "Bash(node --check /d/Code/vb-agent/plugins/weixin-plugin.js 2>&1)",
49
- "Bash(node --check /d/Code/vb-agent/plugins/telegram-plugin.js && node --check /d/Code/vb-agent/plugins/weixin-plugin.js && echo \"OK\")",
50
- "Bash(node --check /d/Code/vb-agent/cli/src/ui/chat-ui.js && echo \"OK\")",
51
- "Bash(npm uninstall:*)",
52
- "Bash(rm -rf /tmp/weixin-bot && git clone https://github.com/chnak/weixin-bot.git /tmp/weixin-bot 2>&1)",
53
- "Bash(mkdir -p node_modules/@pinixai/weixin-bot && cp -r /tmp/weixin-bot/nodejs/* node_modules/@pinixai/weixin-bot/ && cd node_modules/@pinixai/weixin-bot && npm install 2>&1)",
54
- "Bash(node --check /d/Code/vb-agent/plugins/weixin-plugin.js && echo \"OK\")",
55
- "Bash(node -e \"import\\('@pinixai/weixin-bot'\\).then\\(m => console.log\\('OK:', Object.keys\\(m\\)\\)\\).catch\\(e => console.error\\('Error:', e.message\\)\\)\")",
56
- "Bash(npm run:*)",
57
- "Bash(node -e \"const { WeixinBot } = require\\('@pinixai/weixin-bot'\\); console.log\\(typeof WeixinBot\\)\" 2>&1)",
58
- "Bash(node -e \"import\\('@pinixai/weixin-bot'\\).then\\(m => console.log\\('OK:', typeof m.WeixinBot\\)\\).catch\\(e => console.error\\('Error:', e.message\\)\\)\" 2>&1)"
59
- ]
60
- }
61
- }
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(grep -r \"dotenv\" \"D:/Code/vb-agent/\" --include=\"*.json\" 2>/dev/null | head -20)",
5
+ "Bash(cd \"D:/Code/vb-agent\" && pnpm add dotenv)",
6
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(Object.keys\\(ai\\).filter\\(k => k.toLowerCase\\(\\).includes\\('reason'\\) || k.toLowerCase\\(\\).includes\\('split'\\) || k.toLowerCase\\(\\).includes\\('think'\\)\\)\\)\")",
7
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(typeof ai.extractReasoningMiddleware, ai.extractReasoningMiddleware.toString\\(\\).substring\\(0, 500\\)\\)\")",
8
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"\nconst ai = require\\('ai'\\);\nconsole.log\\('=== extractReasoningMiddleware ==='\\);\nconsole.log\\(ai.extractReasoningMiddleware.toString\\(\\)\\);\nconsole.log\\('\\\\n=== isReasoningUIPart ==='\\);\nconsole.log\\(typeof ai.isReasoningUIPart\\);\n\")",
9
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(Object.keys\\(ai\\).filter\\(k => k.toLowerCase\\(\\).includes\\('split'\\)\\)\\)\")",
10
+ "Bash(cd \"D:/Code/vb-agent\" && pnpm add ink react)",
11
+ "Bash(cd \"D:/Code/vb-agent\" && node cli/bin/foliko.js --help)",
12
+ "Bash(cd \"D:/Code/vb-agent\" && timeout 2 node cli/bin/foliko.js chat 2>&1 || true)",
13
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const mt = require\\('marked-terminal'\\); console.log\\(typeof mt, Object.keys\\(mt\\)\\)\")",
14
+ "Bash(cd \"D:/Code/vb-agent\" && timeout 3 node cli/bin/foliko.js chat 2>&1 || true)",
15
+ "Bash(echo \"你好\" | node cli/bin/foliko.js chat 2>&1 | head -50)",
16
+ "Bash(printf '思考一下1+1等于几\\\\n' | node cli/bin/foliko.js chat 2>&1 | head -100)",
17
+ "Bash(printf '1+1等于几\\\\n' | node cli/bin/foliko.js chat 2>&1)",
18
+ "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\nconsole.log\\(renderLine\\('🎉 这是一个 emoji'\\)\\)\nconsole.log\\(renderLine\\('**粗体** 和 🎉'\\)\\)\n\")",
19
+ "Bash(node -e \"\nconst { render } = require\\('./cli/src/utils/markdown'\\)\nconst text = '🎉 今天是个好日子\\\\n## 标题\\\\n- 列表项1\\\\n- 列表项2'\nconsole.log\\(render\\(text\\)\\)\n\")",
20
+ "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\n\n// 模拟emoji被截断的情况\nconst emoji = '🎉'\nconsole.log\\('完整的 emoji:', renderLine\\(emoji\\)\\)\n\n// 模拟截断 - emoji的UTF-8字节是 \\\\xF0\\\\x9F\\\\x8E\\\\x89\nconst partial = '\\\\xF0\\\\x9F' // 不完整的emoji\nconsole.log\\('截断的 emoji:', renderLine\\(partial\\)\\)\n\")",
21
+ "Bash(node -e \"\nconst isIncompleteUTF8 = \\(str\\) => {\n if \\(!str || str.length === 0\\) return false\n const lastChar = str.charCodeAt\\(str.length - 1\\)\n if \\(lastChar >= 0x80 && lastChar < 0xC0\\) return true\n return false\n}\n\n// 测试各种emoji\nconst tests = ['🎉', '📁', '⚡', '🛠️', '🔑', '💾', '📝', '⏰', '🔌', '📋']\ntests.forEach\\(e => {\n console.log\\(e, '完整:', !isIncompleteUTF8\\(e\\)\\)\n}\\)\n\n// 测试被截断的emoji \\(只保留第一字节\\)\nconst broken = '🎉'.slice\\(0, 1\\)\nconsole.log\\('截断emoji:', broken, '检测:', isIncompleteUTF8\\(broken\\)\\)\n\")",
22
+ "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\nconsole.log\\('测试:', renderLine\\('📁 文件操作:读取、创建'\\)\\)\n\")",
23
+ "Bash(node -e \"\nconst hasIncompleteSurrogate = \\(str\\) => {\n if \\(!str || str.length === 0\\) return false\n const lastChar = str.charCodeAt\\(str.length - 1\\)\n console.log\\('检查:', str, 'lastChar:', lastChar.toString\\(16\\), '范围:', \\(lastChar >= 0xD800 && lastChar <= 0xDBFF\\)\\)\n return lastChar >= 0xD800 && lastChar <= 0xDBFF\n}\n\nconst chunk1 = '\\\\xD83C'\nconsole.log\\('结果:', hasIncompleteSurrogate\\(chunk1\\)\\)\n\")",
24
+ "Bash(cd D:/Code/vb-agent && node test-stream-emoji.js 2>&1)",
25
+ "Read(//d/Date/20260321/app/**)",
26
+ "Bash(node -e \":*)",
27
+ "Bash(node -e \"\nconst { loadAgentConfig } = require\\('./plugins/default-plugins'\\);\nconst config = loadAgentConfig\\('D:/Date/20260321/app/.agent'\\);\nconsole.log\\('skillsDirs:', config.skillsDirs\\);\n\")",
28
+ "Bash(cd D:/Code/vb-agent && pnpm install --shamefully-hoist 2>&1 | head -20)",
29
+ "Bash(cd D:/Code/vb-agent && rm -rf node_modules && pnpm install)",
30
+ "Bash(cd D:/Code/vb-agent && timeout 8 node test-tg.js 2>&1 || true)",
31
+ "Bash(cd D:/Code/vb-agent && timeout 10 node test-tg.js 2>&1 || true)",
32
+ "Bash(find /d/Code/vb-agent -name \"*email*\" -type f 2>/dev/null | grep -v node_modules | grep -v .git)",
33
+ "Bash(find /d/Code/vb-agent -maxdepth 2 -name \"*.md\" -type f 2>/dev/null | grep -v node_modules)",
34
+ "Bash(node -c plugins/default-plugins.js && node -c src/core/plugin-manager.js && echo \"Syntax OK\")",
35
+ "Bash(node -c plugins/install-plugin.js && echo \"Syntax OK\")",
36
+ "Bash(node -c cli/src/ui/chat-ui.js && echo \"Syntax OK\")",
37
+ "Bash(node -c plugins/default-plugins.js && echo \"Syntax OK\")",
38
+ "Bash(node -c plugins/scheduler-plugin.js && echo \"Syntax OK\")",
39
+ "Bash(node -c plugins/telegram-plugin.js && node -c plugins/scheduler-plugin.js && echo \"Syntax OK\")",
40
+ "Bash(node -c plugins/telegram-plugin.js && echo \"Syntax OK\")",
41
+ "WebSearch",
42
+ "Bash(npm ls:*)",
43
+ "Bash(cd node_modules/@pinixai/weixin-bot && npm run build 2>&1)",
44
+ "Bash(cd node_modules/@pinixai/weixin-bot && npx tsc 2>&1)",
45
+ "Bash(npm install:*)",
46
+ "Bash(cd node_modules/@pinixai/weixin-bot && npx typescript --version && npx tsc 2>&1)",
47
+ "Bash(npx tsc:*)",
48
+ "Bash(node --check /d/Code/vb-agent/plugins/weixin-plugin.js 2>&1)",
49
+ "Bash(node --check /d/Code/vb-agent/plugins/telegram-plugin.js && node --check /d/Code/vb-agent/plugins/weixin-plugin.js && echo \"OK\")",
50
+ "Bash(node --check /d/Code/vb-agent/cli/src/ui/chat-ui.js && echo \"OK\")",
51
+ "Bash(npm uninstall:*)",
52
+ "Bash(rm -rf /tmp/weixin-bot && git clone https://github.com/chnak/weixin-bot.git /tmp/weixin-bot 2>&1)",
53
+ "Bash(mkdir -p node_modules/@pinixai/weixin-bot && cp -r /tmp/weixin-bot/nodejs/* node_modules/@pinixai/weixin-bot/ && cd node_modules/@pinixai/weixin-bot && npm install 2>&1)",
54
+ "Bash(node --check /d/Code/vb-agent/plugins/weixin-plugin.js && echo \"OK\")",
55
+ "Bash(node -e \"import\\('@pinixai/weixin-bot'\\).then\\(m => console.log\\('OK:', Object.keys\\(m\\)\\)\\).catch\\(e => console.error\\('Error:', e.message\\)\\)\")",
56
+ "Bash(npm run:*)",
57
+ "Bash(node -e \"const { WeixinBot } = require\\('@pinixai/weixin-bot'\\); console.log\\(typeof WeixinBot\\)\" 2>&1)",
58
+ "Bash(node -e \"import\\('@pinixai/weixin-bot'\\).then\\(m => console.log\\('OK:', typeof m.WeixinBot\\)\\).catch\\(e => console.error\\('Error:', e.message\\)\\)\" 2>&1)",
59
+ "Bash(ls -la D:/code/vb-agent/cli/bin/ && cat D:/code/vb-agent/cli/bin/*.js 2>/dev/null | head -50)"
60
+ ]
61
+ }
62
+ }
package/README.md CHANGED
@@ -25,7 +25,7 @@ npm run chat
25
25
  ## 项目结构
26
26
 
27
27
  ```
28
- vb-agent/
28
+ foliko/
29
29
  ├── cli/ # 命令行入口
30
30
  │ └── bin/foliko.js # CLI 入口
31
31
  ├── src/ # 核心框架
package/SPEC.md CHANGED
@@ -134,7 +134,7 @@ class Plugin {
134
134
  ## 三、目录结构
135
135
 
136
136
  ```
137
- D:\code\vb-agent\
137
+ D:\code\foliko\
138
138
  ├── src/
139
139
  │ ├── core/
140
140
  │ │ ├── framework.js # 核心容器
package/cli/src/index.js CHANGED
@@ -7,13 +7,13 @@ const { chatCommand } = require('./commands/chat')
7
7
  /**
8
8
  * CLI 主入口
9
9
  */
10
- function cli() {
10
+ async function cli() {
11
11
  const args = process.argv.slice(2)
12
12
  const command = args[0] || 'chat'
13
13
 
14
14
  switch (command) {
15
15
  case 'chat':
16
- chatCommand(args.slice(1))
16
+ await chatCommand(args.slice(1))
17
17
  break
18
18
 
19
19
  case 'help':
@@ -31,7 +31,7 @@ VB-Agent 是一个基于插件的 Agent 框架,具有以下特性:
31
31
  ### 项目结构
32
32
 
33
33
  ```
34
- vb-agent/
34
+ foliko/
35
35
  ├── src/ # 核心源码
36
36
  │ ├── core/ # 核心模块
37
37
  │ │ ├── framework.js # 框架容器
@@ -733,7 +733,7 @@ module.exports = function(Plugin) {
733
733
  name: my-skill
734
734
  description: 我的技能描述
735
735
  license: MIT
736
- compatibility: vb-agent >= 1.0.0
736
+ compatibility: foliko >= 1.0.0
737
737
  metadata:
738
738
  author: Your Name
739
739
  version: 1.0.0
@@ -753,13 +753,13 @@ Agent 可以通过 `loadSkill` 工具加载技能:
753
753
 
754
754
  ```
755
755
  用户: 帮我创建一个系统信息插件
756
- Agent: [调用 loadSkill 技能 vb-agent-dev]
756
+ Agent: [调用 loadSkill 技能 foliko-dev]
757
757
  Agent: [获取插件开发指南后,按照指南创建插件]
758
758
  ```
759
759
 
760
760
  ### 6.4 内置技能
761
761
 
762
- - **vb-agent-dev** - VB-Agent 插件开发指南
762
+ - **foliko-dev** - VB-Agent 插件开发指南
763
763
  - **api-patterns** - API 设计模式
764
764
  - **app-builder** - 应用程序构建
765
765
  - **architecture** - 架构设计
package/install.ps1 CHANGED
@@ -1,179 +1,110 @@
1
- # Foliko 安装脚本
2
- # 使用方式: irm https://raw.githubusercontent.com/user/vb-agent/main/install.ps1 | iex
1
+ # Foliko Installer
3
2
 
4
- $ErrorActionPreference = "Stop"
3
+ # Fix execution policy first
4
+ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force -ErrorAction SilentlyContinue
5
5
 
6
- $Repo = "your-username/vb-agent"
7
- $InstallDir = "$env:LOCALAPPDATA\Foliko"
8
-
9
- Write-Host "Foliko 安装器" -ForegroundColor Cyan
10
- Write-Host "=================" -ForegroundColor Cyan
6
+ Write-Host "Foliko Installer"
7
+ Write-Host "================="
11
8
  Write-Host ""
12
9
 
13
- # 检查并安装 Node.js
14
- function Install-NodeJS {
15
- Write-Host "正在检查 Node.js..." -ForegroundColor Cyan
16
-
17
- if (Get-Command node -ErrorAction SilentlyContinue) {
18
- Write-Host "Node.js 已安装: $(node --version)" -ForegroundColor Green
19
- return $true
20
- }
10
+ # Refresh PATH
11
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
21
12
 
22
- Write-Host "Node.js 未安装,正在安装..." -ForegroundColor Yellow
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
23
19
 
24
- # 下载 Node.js LTS 安装包
25
20
  $nodeUrl = "https://nodejs.org/dist/v20.11.0/node-v20.11.0-x64.msi"
26
21
  $nodeInstaller = "$env:TEMP\node-installer.msi"
27
22
 
28
- Write-Host "下载 Node.js..." -ForegroundColor Cyan
29
- Invoke-WebRequest -Uri $nodeUrl -OutFile $nodeInstaller
23
+ Write-Host "Downloading Node.js..." -ForegroundColor Cyan
24
+ Invoke-WebRequest -Uri $nodeUrl -OutFile $nodeInstaller -UseBasicParsing
30
25
 
31
- Write-Host "安装 Node.js (需要管理员权限)..." -ForegroundColor Yellow
26
+ Write-Host "Installing Node.js (may require admin)..." -ForegroundColor Cyan
32
27
  Start-Process msiexec.exe -ArgumentList "/i", $nodeInstaller, "/quiet", "/norestart" -Wait
33
28
 
34
- # 刷新环境变量
35
29
  $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
30
+ Start-Sleep -Seconds 3
36
31
 
37
- # 验证安装
38
- Start-Sleep -Seconds 2
39
32
  if (Get-Command node -ErrorAction SilentlyContinue) {
40
- Write-Host "Node.js 安装成功: $(node --version)" -ForegroundColor Green
33
+ Write-Host "Node.js installed: $(node --version)" -ForegroundColor Green
41
34
  Remove-Item $nodeInstaller -Force -ErrorAction SilentlyContinue
42
- return $true
35
+ } else {
36
+ Write-Host "Node.js installation failed" -ForegroundColor Red
37
+ Write-Host "Download manually: https://nodejs.org/" -ForegroundColor Yellow
43
38
  }
44
-
45
- Write-Host "Node.js 安装失败,请手动安装" -ForegroundColor Red
46
- Write-Host "下载地址: https://nodejs.org/" -ForegroundColor Yellow
47
- return $false
48
39
  }
40
+ Write-Host ""
49
41
 
50
- # 检查并安装 Python
51
- function Install-Python {
52
- Write-Host "正在检查 Python..." -ForegroundColor Cyan
53
-
54
- if (Get-Command python -ErrorAction SilentlyContinue) {
55
- Write-Host "Python 已安装: $(python --version)" -ForegroundColor Green
56
- return $true
57
- }
58
-
59
- Write-Host "Python 未安装,正在安装..." -ForegroundColor Yellow
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
60
48
 
61
- # 下载 Python 安装包
62
49
  $pythonUrl = "https://www.python.org/ftp/python/3.12.1/python-3.12.1-amd64.exe"
63
50
  $pythonInstaller = "$env:TEMP\python-installer.exe"
64
51
 
65
- Write-Host "下载 Python..." -ForegroundColor Cyan
66
- Invoke-WebRequest -Uri $pythonUrl -OutFile $pythonInstaller
52
+ Write-Host "Downloading Python..." -ForegroundColor Cyan
53
+ Invoke-WebRequest -Uri $pythonUrl -OutFile $pythonInstaller -UseBasicParsing
67
54
 
68
- Write-Host "安装 Python (需要管理员权限)..." -ForegroundColor Yellow
69
- # 使用静默安装参数,添加 PATH 和 pip
55
+ Write-Host "Installing Python (may require admin)..." -ForegroundColor Cyan
70
56
  Start-Process $pythonInstaller -ArgumentList "/quiet", "InstallAllUsers=1", "PrependPath=1", "Include_pip=1" -Wait
71
57
 
72
- # 刷新环境变量
73
58
  $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
59
+ Start-Sleep -Seconds 3
74
60
 
75
- # 验证安装
76
- Start-Sleep -Seconds 2
77
61
  if (Get-Command python -ErrorAction SilentlyContinue) {
78
- Write-Host "Python 安装成功: $(python --version)" -ForegroundColor Green
62
+ Write-Host "Python installed: $(python --version)" -ForegroundColor Green
79
63
  Remove-Item $pythonInstaller -Force -ErrorAction SilentlyContinue
80
- return $true
64
+ } else {
65
+ Write-Host "Python installation failed" -ForegroundColor Red
66
+ Write-Host "Download manually: https://www.python.org/downloads/" -ForegroundColor Yellow
81
67
  }
82
-
83
- Write-Host "Python 安装失败,请手动安装" -ForegroundColor Red
84
- Write-Host "下载地址: https://www.python.org/downloads/" -ForegroundColor Yellow
85
- return $false
86
68
  }
69
+ Write-Host ""
87
70
 
88
- # 创建 Python 虚拟环境
89
- function Install-PythonVenv {
90
- param([string]$venvDir)
91
-
92
- Write-Host "正在检查 Python venv..." -ForegroundColor Cyan
93
-
94
- if (-not (Get-Command python -ErrorAction SilentlyContinue)) {
95
- Write-Host "Python 未安装,跳过 venv" -ForegroundColor Yellow
96
- return $false
97
- }
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
98
77
 
99
- if (Test-Path $venvDir) {
100
- Write-Host "虚拟环境已存在: $venvDir" -ForegroundColor Green
101
- return $true
102
- }
78
+ Write-Host "Downloading uv..." -ForegroundColor Cyan
79
+ $uvInstaller = "$env:TEMP\uv-installer.pyz"
103
80
 
104
- Write-Host "创建虚拟环境: $venvDir" -ForegroundColor Cyan
105
- python -m venv $venvDir
81
+ try {
82
+ Invoke-WebRequest -Uri "https://astral.sh/uv/install.ps1" -OutFile "$env:TEMP\install-uv.ps1" -UseBasicParsing
83
+ powershell -ExecutionPolicy Bypass -File "$env:TEMP\install-uv.ps1" -Version "0.4.0" -PowerShell -Admin
84
+ Remove-Item "$env:TEMP\install-uv.ps1" -Force -ErrorAction SilentlyContinue
106
85
 
107
- if (Test-Path "$venvDir\Scripts\python.exe") {
108
- Write-Host "虚拟环境创建成功" -ForegroundColor Green
86
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
109
87
 
110
- # 激活并安装基础包
111
- Write-Host "安装基础依赖..." -ForegroundColor Cyan
112
- & "$venvDir\Scripts\pip.exe" install pip --upgrade
113
- return $true
88
+ if (Get-Command uv -ErrorAction SilentlyContinue) {
89
+ Write-Host "uv installed: $(uv --version)" -ForegroundColor Green
90
+ }
91
+ } catch {
92
+ Write-Host "uv installation failed (optional, can be skipped)" -ForegroundColor Yellow
114
93
  }
115
-
116
- Write-Host "虚拟环境创建失败" -ForegroundColor Red
117
- return $false
118
94
  }
119
-
120
- # 主安装流程
121
- Write-Host "环境检查" -ForegroundColor Cyan
122
- Write-Host "-----------" -ForegroundColor Cyan
123
95
  Write-Host ""
124
96
 
125
- # 检查并安装依赖
126
- $nodeOk = Install-NodeJS
127
- Write-Host ""
128
- $pythonOk = Install-Python
129
- Write-Host ""
97
+ # ============ Install Foliko ============
98
+ Write-Host "Installing Foliko..."
99
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
130
100
 
131
- if (-not $nodeOk) {
132
- Write-Host "警告: Node.js 未正确安装,部分功能可能不可用" -ForegroundColor Yellow
133
- }
134
-
135
- if (-not $pythonOk) {
136
- Write-Host "警告: Python 未正确安装,部分功能可能不可用" -ForegroundColor Yellow
137
- }
101
+ npm install -g foliko
138
102
 
139
- # 创建 Python 虚拟环境
140
- $venvDir = "$InstallDir\venv"
141
- if ($pythonOk) {
103
+ if (Get-Command foliko -ErrorAction SilentlyContinue) {
142
104
  Write-Host ""
143
- $venvOk = Install-PythonVenv -venvDir $venvDir
144
- }
145
-
146
- # 创建安装目录
147
- if (-not (Test-Path $InstallDir)) {
148
- New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
149
- }
150
-
151
- Write-Host "安装到: $InstallDir" -ForegroundColor Cyan
152
- Write-Host ""
153
-
154
- Push-Location $InstallDir
155
-
156
- if (Test-Path ".git") {
157
- Write-Host "更新现有安装..." -ForegroundColor Cyan
158
- git pull
105
+ Write-Host "Installation complete!" -ForegroundColor Green
106
+ Write-Host "Run: foliko chat"
159
107
  } else {
160
- Write-Host "下载 Foliko..." -ForegroundColor Cyan
161
- git clone https://github.com/$Repo.git .
108
+ Write-Host ""
109
+ Write-Host "Installation may have failed. Try manually: npm install -g foliko" -ForegroundColor Yellow
162
110
  }
163
-
164
- # 安装依赖
165
- Write-Host "安装 npm 依赖..." -ForegroundColor Cyan
166
- npm install
167
-
168
- # 全局链接 CLI
169
- Write-Host "安装 CLI..." -ForegroundColor Cyan
170
- npm link
171
-
172
- Pop-Location
173
-
174
- Write-Host ""
175
- Write-Host "安装完成!" -ForegroundColor Green
176
- Write-Host ""
177
- Write-Host "使用方法:" -ForegroundColor Yellow
178
- Write-Host " foliko chat" -ForegroundColor White
179
- Write-Host ""
package/install.sh ADDED
@@ -0,0 +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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foliko",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "简约的插件化 Agent 框架",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -26,7 +26,7 @@
26
26
  "@ai-sdk/openai-compatible": "^2.0.35",
27
27
  "@anthropic-ai/sdk": "^0.39.0",
28
28
  "@modelcontextprotocol/sdk": "^1.27.1",
29
- "@pinixai/weixin-bot": "github:chnak/weixin-bot",
29
+ "@pinixai/weixin-bot": "https://github.com/chnak/weixin-bot.git",
30
30
  "ai": "^6.0.116",
31
31
  "dotenv": "^17.3.1",
32
32
  "imap": "^0.8.19",
@@ -127,7 +127,7 @@ class SubAgentPlugin extends Plugin {
127
127
  }
128
128
 
129
129
  // 尝试从framework获取主agent
130
- // 在vb-agent中,主agent通常是通过framework.createAgent创建的
130
+ // 在foliko中,主agent通常是通过framework.createAgent创建的
131
131
  if (this._framework._mainAgent) {
132
132
  return this._framework._mainAgent
133
133
  }
@@ -1,14 +1,14 @@
1
1
  ---
2
- name: vb-agent-dev
3
- description: VB-Agent Framework 插件开发指南。当用户说"创建插件"、"开发插件"时立即调用此 skill。
2
+ name: foliko-dev
3
+ description: Foliko Framework 插件开发指南。当用户说"创建插件"、"开发插件"时立即调用此 skill。
4
4
  allowed-tools: Read, Write, Edit, Glob, Grep, Bash
5
5
  ---
6
6
 
7
- # VB-Agent Plugin Development Guide
7
+ # Foliko Plugin Development Guide
8
8
 
9
9
  ## 概述
10
10
 
11
- VB-Agent 是一个基于插件的 Agent 框架,核心简单,通过插件扩展功能。
11
+ Foliko 是一个基于插件的 Agent 框架,核心简单,通过插件扩展功能。
12
12
 
13
13
  ---
14
14
 
@@ -49,6 +49,29 @@
49
49
  <div class="main-content">
50
50
  <h1>配置指南</h1>
51
51
 
52
+ <h2>环境变量配置 (.env)</h2>
53
+ <p>在项目根目录创建 <code>.env</code> 文件:</p>
54
+ <pre><code># AI Provider: minimax, deepseek, openai, anthropic 等
55
+ FOLIKO_PROVIDER=minimax
56
+
57
+ # AI Model(可选,不填则使用 provider 默认值)
58
+ # MiniMax: MiniMax-M2.7
59
+ # DeepSeek: deepseek-chat, deepseek-coder 等
60
+ FOLIKO_MODEL=
61
+
62
+ # API Base URL(可选,不填则使用 provider 默认值)
63
+ # MiniMax: https://api.minimaxi.com/v1
64
+ # DeepSeek: https://api.deepseek.com/v1
65
+ FOLIKO_BASE_URL=
66
+
67
+ # API Key(通用,不填则使用 provider 专用 key)
68
+ FOLIKO_API_KEY=
69
+
70
+ # Provider 专用 API Key(可选)
71
+ DEEPSEEK_API_KEY=sk-your-deepseek-api-key
72
+ MINIMAX_API_KEY=sk-your-minimax-api-key</code></pre>
73
+ <p><strong>配置优先级</strong>:命令行参数 > .env配置 > provider默认值</p>
74
+
52
75
  <h2>目录结构</h2>
53
76
  <p>在项目根目录创建 <code>.agent</code> 目录:</p>
54
77
  <pre><code>项目目录/
@@ -92,28 +115,159 @@ ai_base_url: https://api.minimaxi.com/v1</code></pre>
92
115
  }</code></pre>
93
116
 
94
117
  <h2>CLI 参数</h2>
118
+ <p>命令行参数会覆盖 .env 配置:</p>
95
119
  <table>
96
120
  <tr>
97
121
  <th>参数</th>
98
122
  <th>说明</th>
99
- </tr>
100
- <tr>
101
- <td><code>--model</code></td>
102
- <td>指定 AI 模型</td>
123
+ <th>示例</th>
103
124
  </tr>
104
125
  <tr>
105
126
  <td><code>--provider</code></td>
106
127
  <td>指定 AI 提供商</td>
128
+ <td><code>deepseek</code>, <code>minimax</code></td>
107
129
  </tr>
108
130
  <tr>
109
- <td><code>--api-key</code></td>
110
- <td>指定 API 密钥</td>
131
+ <td><code>--model</code></td>
132
+ <td>指定 AI 模型</td>
133
+ <td><code>deepseek-chat</code>, <code>MiniMax-M2.7</code></td>
111
134
  </tr>
112
135
  <tr>
113
136
  <td><code>--base-url</code></td>
114
137
  <td>指定 API 地址</td>
138
+ <td><code>https://api.deepseek.com/v1</code></td>
139
+ </tr>
140
+ <tr>
141
+ <td><code>--api-key</code></td>
142
+ <td>指定 API 密钥</td>
143
+ <td><code>sk-xxx</code></td>
115
144
  </tr>
116
145
  </table>
146
+
147
+ <h3>使用示例</h3>
148
+ <pre><code># 使用 .env 中的配置
149
+ npm run chat
150
+
151
+ # 指定完整配置
152
+ foliko chat --provider deepseek --model deepseek-chat --base-url https://api.deepseek.com/v1 --api-key sk-xxx
153
+
154
+ # 只指定 provider(使用 provider 默认 model 和 baseURL)
155
+ foliko chat --provider deepseek --api-key sk-xxx
156
+
157
+ # 只指定 api-key(使用 FOLIKO_PROVIDER 设定的 provider)
158
+ foliko chat --api-key sk-xxx</code></pre>
159
+
160
+ <h2>插件配置</h2>
161
+
162
+ <h3>Telegram 插件</h3>
163
+ <pre><code>{
164
+ "telegram": {
165
+ "botToken": "your-bot-token",
166
+ "allowedChats": ["123456789"],
167
+ "groupMode": false,
168
+ "prefix": "/"
169
+ }
170
+ }</code></pre>
171
+ <table>
172
+ <tr><th>配置项</th><th>说明</th><th>默认值</th></tr>
173
+ <tr><td>botToken</td><td>Telegram Bot Token</td><td>TELEGRAM_BOT_TOKEN 环境变量</td></tr>
174
+ <tr><td>allowedChats</td><td>允许的聊天 ID 数组</td><td>[] (允许所有人)</td></tr>
175
+ <tr><td>groupMode</td><td>是否启用群组模式</td><td>false</td></tr>
176
+ <tr><td>prefix</td><td>命令前缀</td><td>/</td></tr>
177
+ </table>
178
+
179
+ <h3>WeChat 插件</h3>
180
+ <pre><code>{
181
+ "weixin": {
182
+ "forceLogin": false,
183
+ "qrcodeTerminal": true,
184
+ "allowedUsers": []
185
+ }
186
+ }</code></pre>
187
+ <table>
188
+ <tr><th>配置项</th><th>说明</th><th>默认值</th></tr>
189
+ <tr><td>forceLogin</td><td>强制重新扫码登录</td><td>false</td></tr>
190
+ <tr><td>qrcodeTerminal</td><td>终端渲染二维码</td><td>true</td></tr>
191
+ <tr><td>allowedUsers</td><td>允许的用户 ID 数组</td><td>[] (允许所有人)</td></tr>
192
+ </table>
193
+
194
+ <h3>Session 插件</h3>
195
+ <pre><code>{
196
+ "session": {
197
+ "sessionTTL": 1800000,
198
+ "maxSessions": 100,
199
+ "maxHistoryLength": 50,
200
+ "autoCleanup": true,
201
+ "cleanupInterval": 300000
202
+ }
203
+ }</code></pre>
204
+ <table>
205
+ <tr><th>配置项</th><th>说明</th><th>默认值</th></tr>
206
+ <tr><td>sessionTTL</td><td>会话过期时间(毫秒)</td><td>30分钟</td></tr>
207
+ <tr><td>maxSessions</td><td>最大会话数</td><td>100</td></tr>
208
+ <tr><td>maxHistoryLength</td><td>最大历史消息数</td><td>50</td></tr>
209
+ <tr><td>autoCleanup</td><td>自动清理过期会话</td><td>true</td></tr>
210
+ <tr><td>cleanupInterval</td><td>清理检查间隔(毫秒)</td><td>5分钟</td></tr>
211
+ </table>
212
+
213
+ <h3>Storage 插件</h3>
214
+ <pre><code>{
215
+ "storage": {
216
+ "type": "json",
217
+ "path": ".agent/data",
218
+ "namespace": "default"
219
+ }
220
+ }</code></pre>
221
+ <table>
222
+ <tr><th>配置项</th><th>说明</th><th>默认值</th></tr>
223
+ <tr><td>type</td><td>存储类型 (json/memory)</td><td>json</td></tr>
224
+ <tr><td>path</td><td>存储文件路径</td><td>.agent/data</td></tr>
225
+ <tr><td>namespace</td><td>命名空间</td><td>default</td></tr>
226
+ </table>
227
+
228
+ <h3>Scheduler 插件</h3>
229
+ <pre><code>{
230
+ "scheduler": {
231
+ "checkInterval": 1000
232
+ }
233
+ }</code></pre>
234
+ <table>
235
+ <tr><th>配置项</th><th>说明</th><th>默认值</th></tr>
236
+ <tr><td>checkInterval</td><td>任务检查间隔(毫秒)</td><td>1000</td></tr>
237
+ </table>
238
+
239
+ <h3>Email 插件</h3>
240
+ <p>通过环境变量配置:</p>
241
+ <pre><code># SMTP 配置 (发送邮件)
242
+ SMTP_HOST=smtp.gmail.com
243
+ SMTP_PORT=587
244
+ SMTP_SECURE=false
245
+ SMTP_USER=your-email@gmail.com
246
+ SMTP_PASS=your-app-password
247
+
248
+ # IMAP 配置 (读取邮件)
249
+ IMAP_HOST=imap.gmail.com
250
+ IMAP_PORT=993
251
+ IMAP_USER=your-email@gmail.com
252
+ IMAP_PASS=your-app-password
253
+
254
+ # 默认发件人
255
+ FROM_EMAIL=your-email@gmail.com</code></pre>
256
+
257
+ <h3>MCP 配置</h3>
258
+ <p>在 <code>.agent/mcp_config.json</code> 中配置 MCP 服务器:</p>
259
+ <pre><code>{
260
+ "mcpServers": {
261
+ "fetch": {
262
+ "command": "npx",
263
+ "args": ["-y", "@modelcontextprotocol/server-fetch"]
264
+ },
265
+ "filesystem": {
266
+ "command": "npx",
267
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
268
+ }
269
+ }
270
+ }</code></pre>
117
271
  </div>
118
272
  </body>
119
273
  </html>
@@ -48,10 +48,6 @@
48
48
  <div class="main-content">
49
49
  <h1>插件开发</h1>
50
50
 
51
- <div class="warning">
52
- <strong>重要:</strong> 禁止创建目录!插件必须是单个 `.js` 文件。
53
- </div>
54
-
55
51
  <h2>快速开始</h2>
56
52
  <p>在 <code>.agent/plugins/</code> 目录下创建插件文件:</p>
57
53
  <pre><code>// .agent/plugins/my-plugin.js
@@ -96,7 +96,7 @@
96
96
  <h1>项目结构</h1>
97
97
 
98
98
  <h2>目录结构</h2>
99
- <pre><code>vb-agent/
99
+ <pre><code>foliko/
100
100
  ├── cli/ # 命令行入口
101
101
  │ ├── bin/foliko.js # CLI 入口脚本
102
102
  │ └── src/
@@ -22,14 +22,28 @@
22
22
 
23
23
  <main>
24
24
  <section id="home" class="hero">
25
- <h1>Foliko</h1>
26
- <p class="tagline">简约的插件化 Agent 框架</p>
27
- <p class="description">
28
- 核心简单,功能强大。通过插件扩展无限可能。
29
- </p>
30
- <div class="cta-buttons">
31
- <a href="#quickstart" class="btn btn-primary">快速开始</a>
32
- <a href="https://github.com/your-username/vb-agent" class="btn btn-secondary">GitHub</a>
25
+ <div class="hero-content">
26
+ <h1>Foliko</h1>
27
+ <p class="tagline">简约的插件化 Agent 框架</p>
28
+
29
+ <div class="install-box">
30
+ <div class="install-tabs">
31
+ <button class="tab active" data-cmd="irm https://foliko.com/install.ps1 | iex">Windows</button>
32
+ <button class="tab" data-cmd="curl -fsSL https://foliko.com/install.sh | bash">Mac / Linux</button>
33
+ <button class="tab" data-cmd="npm install -g foliko">npm</button>
34
+ </div>
35
+ <div class="install-cmd">
36
+ <code id="install-cmd">irm https://foliko.com/install.ps1 | iex</code>
37
+ <button class="copy-btn" onclick="copyCmd()">复制</button>
38
+ </div>
39
+ </div>
40
+
41
+ <div class="hero-links">
42
+ <a href="#features">核心特性</a>
43
+ <a href="#quickstart">快速开始</a>
44
+ <a href="#docs">文档</a>
45
+ <a href="#plugins">插件</a>
46
+ </div>
33
47
  </div>
34
48
  </section>
35
49
 
@@ -72,27 +86,19 @@
72
86
  <section id="quickstart" class="quickstart">
73
87
  <h2>快速开始</h2>
74
88
 
75
- <div class="code-block">
76
- <h3>安装</h3>
77
- <pre><code># PowerShell (Windows)
78
- irm https://raw.githubusercontent.com/your-username/vb-agent/main/install.ps1 | iex
79
-
80
- # 或者克隆仓库
81
- git clone https://github.com/your-username/vb-agent.git
82
- cd vb-agent
83
- npm install
84
- npm link</code></pre>
85
- </div>
86
-
87
89
  <div class="code-block">
88
90
  <h3>配置</h3>
89
- <pre><code># 创建配置目录
90
- mkdir .agent
91
+ <pre><code># 创建 .env 文件
92
+ touch .env
91
93
 
92
- # 创建配置文件
93
- echo "ai_key: your-api-key" > .agent/config
94
- echo "ai_model: MiniMax-M2.7" >> .agent/config
95
- echo "ai_provider: minimax" >> .agent/config</code></pre>
94
+ # 编辑 .env 添加配置
95
+ # MiniMax 示例:
96
+ # FOLIKO_PROVIDER=minimax
97
+ # MINIMAX_API_KEY=sk-your-api-key
98
+
99
+ # DeepSeek 示例:
100
+ # FOLIKO_PROVIDER=deepseek
101
+ # DEEPSEEK_API_KEY=sk-your-api-key</code></pre>
96
102
  </div>
97
103
 
98
104
  <div class="code-block">
@@ -131,53 +137,81 @@ echo "ai_provider: minimax" >> .agent/config</code></pre>
131
137
  <th>插件</th>
132
138
  <th>说明</th>
133
139
  <th>工具</th>
140
+ <th>配置</th>
134
141
  </tr>
135
142
  </thead>
136
143
  <tbody>
137
144
  <tr>
138
- <td>AI</td>
145
+ <td><strong>AI</strong></td>
139
146
  <td>AI 提供商集成</td>
140
147
  <td>chat, chatStream</td>
148
+ <td>provider, model, apiKey, baseURL</td>
149
+ </tr>
150
+ <tr>
151
+ <td><strong>Session</strong></td>
152
+ <td>会话管理,多会话隔离、历史记录</td>
153
+ <td>session_create, session_get, session_list, session_delete, session_history</td>
154
+ <td>sessionTTL, maxSessions, maxHistoryLength</td>
155
+ </tr>
156
+ <tr>
157
+ <td><strong>Telegram</strong></td>
158
+ <td>Telegram Bot 对话</td>
159
+ <td>Bot 接收消息,自动对话</td>
160
+ <td>botToken, allowedChats, groupMode, prefix</td>
161
+ </tr>
162
+ <tr>
163
+ <td><strong>WeChat</strong></td>
164
+ <td>微信对话</td>
165
+ <td>Bot 接收消息,自动对话</td>
166
+ <td>forceLogin, qrcodeTerminal, allowedUsers</td>
141
167
  </tr>
142
168
  <tr>
143
- <td>Storage</td>
144
- <td>数据持久化</td>
145
- <td>save, load, delete</td>
169
+ <td><strong>Storage</strong></td>
170
+ <td>数据持久化存储</td>
171
+ <td>storage_set, storage_get, storage_delete, storage_list, storage_clear</td>
172
+ <td>type (json/memory), path, namespace</td>
146
173
  </tr>
147
174
  <tr>
148
- <td>Tools</td>
149
- <td>内置工具集</td>
150
- <td>多个工具</td>
175
+ <td><strong>Scheduler</strong></td>
176
+ <td>定时任务调度</td>
177
+ <td>schedule_task, schedule_list, schedule_cancel, cron_examples</td>
178
+ <td>checkInterval</td>
151
179
  </tr>
152
180
  <tr>
153
- <td>Workflow</td>
154
- <td>工作流引擎</td>
155
- <td>workflow_execute</td>
181
+ <td><strong>Email</strong></td>
182
+ <td>邮件收发</td>
183
+ <td>email_send, email_read, email_unread_count, email_mark_read, email_configure</td>
184
+ <td>SMTP/IMAP 配置</td>
156
185
  </tr>
157
186
  <tr>
158
- <td>Shell</td>
187
+ <td><strong>Shell</strong></td>
159
188
  <td>Shell 命令执行</td>
160
189
  <td>shell_execute</td>
190
+ <td>-</td>
161
191
  </tr>
162
192
  <tr>
163
- <td>Python</td>
193
+ <td><strong>Python</strong></td>
164
194
  <td>Python 代码执行</td>
165
195
  <td>python_execute</td>
196
+ <td>-</td>
166
197
  </tr>
167
198
  <tr>
168
- <td>MCP</td>
199
+ <td><strong>MCP</strong></td>
169
200
  <td>MCP 协议支持</td>
170
201
  <td>mcp_execute, mcp_reload</td>
202
+ <td>mcp_config.json</td>
171
203
  </tr>
172
204
  <tr>
173
- <td>Session</td>
174
- <td>会话管理</td>
175
- <td>session_*</td>
205
+ <td><strong>Install</strong></td>
206
+ <td>npm 包安装</td>
207
+ <td>install</td>
208
+ <td>-</td>
176
209
  </tr>
177
210
  <tr>
178
- <td>Audit</td>
211
+ <td><strong>Audit</strong></td>
179
212
  <td>审计日志</td>
180
213
  <td>audit_query</td>
214
+ <td>-</td>
181
215
  </tr>
182
216
  </tbody>
183
217
  </table>
@@ -187,7 +221,7 @@ echo "ai_provider: minimax" >> .agent/config</code></pre>
187
221
  <footer>
188
222
  <p>&copy; 2024 Foliko. MIT License.</p>
189
223
  <p>
190
- <a href="https://github.com/your-username/vb-agent">GitHub</a> |
224
+ <a href="https://www.npmjs.com/package/foliko">npm</a> |
191
225
  <a href="docs/api.html">API 文档</a>
192
226
  </p>
193
227
  </footer>
package/website/script.js CHANGED
@@ -1,3 +1,59 @@
1
+ // Install tab switching
2
+ document.querySelectorAll('.install-tabs .tab').forEach(tab => {
3
+ tab.addEventListener('click', () => {
4
+ document.querySelectorAll('.install-tabs .tab').forEach(t => t.classList.remove('active'));
5
+ tab.classList.add('active');
6
+ document.getElementById('install-cmd').textContent = tab.dataset.cmd;
7
+ });
8
+ });
9
+
10
+ // Copy install command
11
+ function copyCmd() {
12
+ const code = document.getElementById('install-cmd').textContent;
13
+ const btn = document.querySelector('.install-cmd .copy-btn');
14
+
15
+ // 复制到剪贴板
16
+ if (navigator.clipboard && navigator.clipboard.writeText) {
17
+ navigator.clipboard.writeText(code).then(() => {
18
+ btn.textContent = '已复制';
19
+ btn.classList.add('copied');
20
+ setTimeout(() => {
21
+ btn.textContent = '复制';
22
+ btn.classList.remove('copied');
23
+ }, 2000);
24
+ }).catch(() => {
25
+ fallbackCopy(code, btn);
26
+ });
27
+ } else {
28
+ fallbackCopy(code, btn);
29
+ }
30
+ }
31
+
32
+ // 备用复制方法
33
+ function fallbackCopy(text, btn) {
34
+ const textarea = document.createElement('textarea');
35
+ textarea.value = text;
36
+ textarea.style.position = 'fixed';
37
+ textarea.style.opacity = '0';
38
+ document.body.appendChild(textarea);
39
+ textarea.select();
40
+ try {
41
+ document.execCommand('copy');
42
+ btn.textContent = '已复制';
43
+ btn.classList.add('copied');
44
+ setTimeout(() => {
45
+ btn.textContent = '复制';
46
+ btn.classList.remove('copied');
47
+ }, 2000);
48
+ } catch (err) {
49
+ btn.textContent = '复制失败';
50
+ setTimeout(() => {
51
+ btn.textContent = '复制';
52
+ }, 2000);
53
+ }
54
+ document.body.removeChild(textarea);
55
+ }
56
+
1
57
  // Smooth scrolling
2
58
  document.querySelectorAll('a[href^="#"]').forEach(anchor => {
3
59
  anchor.addEventListener('click', function (e) {
@@ -69,14 +69,17 @@ nav {
69
69
  .hero {
70
70
  min-height: 100vh;
71
71
  display: flex;
72
- flex-direction: column;
73
- justify-content: center;
74
72
  align-items: center;
75
- text-align: center;
76
- padding: 6rem 2rem 4rem;
73
+ justify-content: center;
74
+ padding: 6rem 2rem;
77
75
  background: linear-gradient(180deg, var(--bg-dark) 0%, var(--bg-card) 100%);
78
76
  }
79
77
 
78
+ .hero-content {
79
+ text-align: center;
80
+ max-width: 600px;
81
+ }
82
+
80
83
  .hero h1 {
81
84
  font-size: 4rem;
82
85
  font-weight: 800;
@@ -84,27 +87,112 @@ nav {
84
87
  -webkit-background-clip: text;
85
88
  -webkit-text-fill-color: transparent;
86
89
  background-clip: text;
87
- margin-bottom: 1rem;
90
+ margin-bottom: 0.5rem;
88
91
  }
89
92
 
90
93
  .tagline {
91
94
  font-size: 1.5rem;
92
95
  color: var(--text-secondary);
93
- margin-bottom: 1rem;
96
+ margin-bottom: 2rem;
97
+ }
98
+
99
+ /* Install Box */
100
+ .install-box {
101
+ background: var(--bg-card);
102
+ border: 1px solid var(--border);
103
+ border-radius: 12px;
104
+ overflow: hidden;
105
+ margin: 0 auto 2rem;
106
+ text-align: left;
107
+ min-width: 600px;
108
+ }
109
+
110
+ .install-tabs {
111
+ display: flex;
112
+ background: var(--bg-dark);
113
+ border-bottom: 1px solid var(--border);
94
114
  }
95
115
 
96
- .description {
97
- font-size: 1.1rem;
116
+ .install-tabs .tab {
117
+ flex: 1;
118
+ min-width: 100px;
119
+ padding: 0.75rem 1rem;
120
+ background: transparent;
121
+ border: none;
98
122
  color: var(--text-secondary);
99
- max-width: 600px;
100
- margin-bottom: 2rem;
123
+ font-size: 0.9rem;
124
+ cursor: pointer;
125
+ transition: all 0.2s;
126
+ }
127
+
128
+ .install-tabs .tab:hover {
129
+ color: var(--text-primary);
130
+ background: rgba(255,255,255,0.03);
101
131
  }
102
132
 
103
- .cta-buttons {
133
+ .install-tabs .tab.active {
134
+ color: var(--primary);
135
+ background: var(--bg-card);
136
+ }
137
+
138
+ .install-cmd {
104
139
  display: flex;
140
+ align-items: center;
141
+ justify-content: space-between;
142
+ padding: 1rem 1.25rem;
105
143
  gap: 1rem;
106
144
  }
107
145
 
146
+ .install-cmd code {
147
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
148
+ font-size: 0.9rem;
149
+ color: var(--secondary);
150
+ flex: 1;
151
+ }
152
+
153
+ .copy-btn {
154
+ background: transparent;
155
+ color: var(--text-secondary);
156
+ border: 1px solid var(--border);
157
+ border-radius: 6px;
158
+ padding: 0.4rem 0.75rem;
159
+ font-size: 0.8rem;
160
+ cursor: pointer;
161
+ transition: all 0.2s;
162
+ white-space: nowrap;
163
+ }
164
+
165
+ .copy-btn:hover {
166
+ color: var(--text-primary);
167
+ border-color: var(--primary);
168
+ background: rgba(99, 102, 241, 0.1);
169
+ }
170
+
171
+ .copy-btn.copied {
172
+ color: #22c55e;
173
+ border-color: #22c55e;
174
+ background: rgba(34, 197, 94, 0.1);
175
+ }
176
+
177
+ /* Hero Links */
178
+ .hero-links {
179
+ display: flex;
180
+ justify-content: center;
181
+ gap: 1.5rem;
182
+ flex-wrap: wrap;
183
+ }
184
+
185
+ .hero-links a {
186
+ color: var(--text-secondary);
187
+ text-decoration: none;
188
+ font-size: 0.95rem;
189
+ transition: color 0.2s;
190
+ }
191
+
192
+ .hero-links a:hover {
193
+ color: var(--primary);
194
+ }
195
+
108
196
  .btn {
109
197
  padding: 0.75rem 1.5rem;
110
198
  border-radius: 8px;
@@ -288,10 +376,39 @@ footer a:hover {
288
376
 
289
377
  /* Responsive */
290
378
  @media (max-width: 768px) {
379
+ .hero {
380
+ padding: 5rem 1rem 3rem;
381
+ min-height: auto;
382
+ }
383
+
291
384
  .hero h1 {
292
385
  font-size: 2.5rem;
293
386
  }
294
387
 
388
+ .hero .tagline {
389
+ font-size: 1.2rem;
390
+ }
391
+
392
+ .install-box {
393
+ min-width: auto;
394
+ width: 100%;
395
+ }
396
+
397
+ .install-tabs .tab {
398
+ min-width: 80px;
399
+ padding: 0.6rem 0.5rem;
400
+ font-size: 0.8rem;
401
+ }
402
+
403
+ .install-cmd code {
404
+ font-size: 0.75rem;
405
+ word-break: break-all;
406
+ }
407
+
408
+ .hero-links {
409
+ gap: 1rem;
410
+ }
411
+
295
412
  .nav-links {
296
413
  display: none;
297
414
  }