myagent-ai 1.15.57 → 1.15.58
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/README.md +16 -24
- package/install/install.ps1 +51 -262
- package/install/install.sh +70 -426
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
### 🚀 执行引擎
|
|
12
12
|
- **多语言执行**: Python / Shell (Bash) / PowerShell / CMD
|
|
13
|
-
- **自动修复**: ImportError 自动安装、编码修复、缩进修复
|
|
14
13
|
- **安全控制**: 危险命令拦截、超时控制、输出截断
|
|
15
14
|
- **结构化结果**: 执行结果标准化,LLM 稳定理解
|
|
16
15
|
|
|
@@ -123,27 +122,18 @@ powershell -c "irm https://raw.githubusercontent.com/ctz168/myagent/main/install
|
|
|
123
122
|
curl -fsSL https://raw.githubusercontent.com/ctz168/myagent/main/install/install.sh | bash
|
|
124
123
|
```
|
|
125
124
|
|
|
126
|
-
###
|
|
125
|
+
### 快速升级
|
|
127
126
|
|
|
128
|
-
> 已安装过 MyAgent
|
|
127
|
+
> 已安装过 MyAgent 的环境下,重新安装最新版:
|
|
129
128
|
|
|
130
|
-
**npm 方式(推荐,最简单):**
|
|
131
129
|
```bash
|
|
132
|
-
|
|
130
|
+
npm install -g myagent-ai@latest
|
|
131
|
+
myagent-ai reinstall
|
|
133
132
|
```
|
|
134
133
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
**脚本方式:**
|
|
138
|
-
|
|
139
|
-
**Windows(PowerShell):**
|
|
140
|
-
```powershell
|
|
141
|
-
powershell -c "& ([scriptblock]::Create((irm https://raw.githubusercontent.com/ctz168/myagent/main/install/install.ps1))) -NoDeps"
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
**macOS / Linux:**
|
|
134
|
+
或使用脚本重新安装:
|
|
145
135
|
```bash
|
|
146
|
-
curl -fsSL https://raw.githubusercontent.com/ctz168/myagent/main/install/install.sh | bash
|
|
136
|
+
curl -fsSL https://raw.githubusercontent.com/ctz168/myagent/main/install/install.sh | bash
|
|
147
137
|
```
|
|
148
138
|
|
|
149
139
|
---
|
|
@@ -200,19 +190,21 @@ export MYAGENT_ANTHROPIC_API_KEY="sk-ant-..."
|
|
|
200
190
|
### 2. 运行
|
|
201
191
|
|
|
202
192
|
```bash
|
|
203
|
-
#
|
|
204
|
-
myagent-ai
|
|
193
|
+
# Web 管理后台(推荐)
|
|
194
|
+
myagent-ai web
|
|
205
195
|
|
|
206
|
-
#
|
|
207
|
-
myagent-ai
|
|
196
|
+
# CLI 交互模式
|
|
197
|
+
myagent-ai cli
|
|
208
198
|
|
|
209
|
-
#
|
|
210
|
-
myagent-ai
|
|
199
|
+
# 系统托盘后台运行
|
|
200
|
+
myagent-ai tray
|
|
211
201
|
|
|
212
|
-
#
|
|
213
|
-
myagent-ai
|
|
202
|
+
# API 服务模式
|
|
203
|
+
myagent-ai server
|
|
214
204
|
```
|
|
215
205
|
|
|
206
|
+
> 首次运行会自动安装所有依赖,后续启动秒开。
|
|
207
|
+
|
|
216
208
|
### 3. 配置聊天平台 (可选)
|
|
217
209
|
|
|
218
210
|
编辑 `~/.myagent/config.json`:
|
package/install/install.ps1
CHANGED
|
@@ -11,7 +11,6 @@ $ErrorActionPreference = "Stop"
|
|
|
11
11
|
$PKG_NAME = "myagent-ai"
|
|
12
12
|
$PKG_VERSION = ""
|
|
13
13
|
|
|
14
|
-
# 动态获取 npm 最新版本号
|
|
15
14
|
function Get-NpmVersion {
|
|
16
15
|
try {
|
|
17
16
|
$ver = (npm view $PKG_NAME version 2>$null)
|
|
@@ -19,12 +18,10 @@ function Get-NpmVersion {
|
|
|
19
18
|
} catch {}
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
# Allow running scripts for the current process
|
|
23
21
|
if ($PSVersionTable.PSVersion.Major -ge 5) {
|
|
24
22
|
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
# 尝试获取最新版本
|
|
28
25
|
Get-NpmVersion
|
|
29
26
|
|
|
30
27
|
$verDisplay = if ($PKG_VERSION) { " v$PKG_VERSION" } else { "" }
|
|
@@ -40,16 +37,13 @@ if ($PSVersionTable.PSVersion.Major -lt 5) {
|
|
|
40
37
|
Write-Host "[OK] Windows detected" -ForegroundColor Green
|
|
41
38
|
|
|
42
39
|
# ── Python ───────────────────────────────────────────────
|
|
43
|
-
# 记录已找到的 Python 路径
|
|
44
40
|
$Script:PythonCmd = ""
|
|
45
41
|
|
|
46
42
|
function Refresh-Path {
|
|
47
|
-
# 刷新 PATH(安装后需要刷新才能找到新安装的程序)
|
|
48
43
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
49
44
|
}
|
|
50
45
|
|
|
51
46
|
function Check-Python {
|
|
52
|
-
# 刷新 PATH(安装后可能需要刷新)
|
|
53
47
|
Refresh-Path
|
|
54
48
|
try {
|
|
55
49
|
$pyVer = (python --version 2>$null)
|
|
@@ -59,119 +53,44 @@ function Check-Python {
|
|
|
59
53
|
$Script:PythonCmd = "python"
|
|
60
54
|
Write-Host "[OK] Python $verNum found" -ForegroundColor Green
|
|
61
55
|
return $true
|
|
62
|
-
} else {
|
|
63
|
-
Write-Host "[!] Python $verNum found, upgrading to 3.13+ ..." -ForegroundColor Yellow
|
|
64
|
-
# 仍然记录当前可用的 Python(即使版本低,也总比没有好)
|
|
65
|
-
$Script:PythonCmd = "python"
|
|
66
|
-
return $false
|
|
67
56
|
}
|
|
68
57
|
}
|
|
69
|
-
} catch {
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
# 尝试在常见安装路径查找
|
|
73
|
-
$commonPaths = @(
|
|
58
|
+
} catch {}
|
|
59
|
+
foreach ($pyPath in @(
|
|
74
60
|
"$env:LOCALAPPDATA\Programs\Python\Python314\python.exe",
|
|
75
61
|
"$env:LOCALAPPDATA\Programs\Python\Python313\python.exe",
|
|
76
|
-
"C:\Python314\python.exe",
|
|
77
|
-
|
|
78
|
-
"C:\Program Files\Python314\python.exe",
|
|
79
|
-
"C:\Program Files\Python313\python.exe"
|
|
80
|
-
)
|
|
81
|
-
foreach ($pyPath in $commonPaths) {
|
|
62
|
+
"C:\Python314\python.exe", "C:\Python313\python.exe"
|
|
63
|
+
)) {
|
|
82
64
|
if (Test-Path $pyPath) {
|
|
83
|
-
$
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Write-Host "[OK] Python $verNum found at $pyPath" -ForegroundColor Green
|
|
87
|
-
return $true
|
|
88
|
-
}
|
|
65
|
+
$Script:PythonCmd = $pyPath
|
|
66
|
+
Write-Host "[OK] Python found at $pyPath" -ForegroundColor Green
|
|
67
|
+
return $true
|
|
89
68
|
}
|
|
90
69
|
}
|
|
91
70
|
return $false
|
|
92
71
|
}
|
|
93
72
|
|
|
94
73
|
function Install-Python {
|
|
95
|
-
Write-Host "[*] Installing Python 3.13 ..." -ForegroundColor Yellow
|
|
96
|
-
$installAttempted = $false
|
|
97
|
-
|
|
98
|
-
# Try winget first (try 3.14, then 3.13)
|
|
74
|
+
Write-Host "[*] Installing Python 3.13+ ..." -ForegroundColor Yellow
|
|
99
75
|
try {
|
|
100
76
|
$null = (winget --version 2>$null)
|
|
101
|
-
Write-Host " Using winget ..." -ForegroundColor Gray
|
|
102
77
|
foreach ($pyVer in @("3.14", "3.13")) {
|
|
103
|
-
Write-Host " 尝试 Python $pyVer ..." -ForegroundColor Gray
|
|
104
78
|
winget install "Python.Python.$pyVer" --accept-package-agreements --accept-source-agreements 2>$null
|
|
105
|
-
$installAttempted = $true
|
|
106
|
-
# 等待安装完成后刷新 PATH(重试多次)
|
|
107
79
|
for ($i = 1; $i -le 5; $i++) {
|
|
108
80
|
Start-Sleep -Seconds 2
|
|
109
81
|
if (Check-Python) { return }
|
|
110
82
|
}
|
|
111
|
-
# winget 已完成安装,即使 Check-Python 失败也不再重复安装
|
|
112
|
-
Refresh-Path
|
|
113
|
-
$pyPaths = @(
|
|
114
|
-
"$env:LOCALAPPDATA\Programs\Python\Python$pyVer\python.exe",
|
|
115
|
-
"C:\Python$pyVer\python.exe",
|
|
116
|
-
"C:\Program Files\Python$pyVer\python.exe"
|
|
117
|
-
)
|
|
118
|
-
foreach ($pyPath in $pyPaths) {
|
|
119
|
-
if (Test-Path $pyPath) {
|
|
120
|
-
$verNum = (& $pyPath --version 2>$null) -replace 'Python\s+(\S+)', '$1'
|
|
121
|
-
if ($verNum) {
|
|
122
|
-
$Script:PythonCmd = $pyPath
|
|
123
|
-
Write-Host "[OK] Python $verNum installed via winget at $pyPath" -ForegroundColor Green
|
|
124
|
-
Write-Host "[i] PATH will be updated after restart. Using direct path for now." -ForegroundColor Gray
|
|
125
|
-
return
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
83
|
}
|
|
130
|
-
Write-Host "[i] Python
|
|
131
|
-
Write-Host " Please restart your terminal and run: myagent-ai" -ForegroundColor Yellow
|
|
84
|
+
Write-Host "[i] Python installed but PATH not updated. Restart terminal and run: myagent-ai" -ForegroundColor Yellow
|
|
132
85
|
exit 0
|
|
133
|
-
} catch {
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
# 仅在 winget 未尝试时才从 python.org 下载(避免双重安装)
|
|
138
|
-
if (-not $installAttempted) {
|
|
139
|
-
# Fallback: download from python.org (try 3.13 first)
|
|
140
|
-
$pyVersions = @(
|
|
141
|
-
@{ Url = "https://www.python.org/ftp/python/3.13.3/python-3.13.3-amd64.exe"; Ver = "3.13.3" },
|
|
142
|
-
@{ Url = "https://www.python.org/ftp/python/3.14.0/python-3.14.0-amd64.exe"; Ver = "3.14.0" }
|
|
143
|
-
)
|
|
144
|
-
foreach ($pyInfo in $pyVersions) {
|
|
145
|
-
$pyExe = Join-Path $env:TEMP "python-installer.exe"
|
|
146
|
-
try {
|
|
147
|
-
Write-Host " Downloading Python $($pyInfo.Ver) ..." -ForegroundColor Gray
|
|
148
|
-
Invoke-WebRequest -Uri $pyInfo.Url -OutFile $pyExe -UseBasicParsing -ErrorAction Stop
|
|
149
|
-
|
|
150
|
-
Write-Host " Installing (Add to PATH) ..." -ForegroundColor Gray
|
|
151
|
-
Start-Process -FilePath $pyExe -ArgumentList "/quiet InstallAllUsers=1 PrependPath=1" -Wait
|
|
152
|
-
|
|
153
|
-
# 刷新 PATH 并验证(重试多次)
|
|
154
|
-
for ($i = 1; $i -le 5; $i++) {
|
|
155
|
-
Start-Sleep -Seconds 2
|
|
156
|
-
if (Check-Python) { return }
|
|
157
|
-
}
|
|
158
|
-
} catch {
|
|
159
|
-
Write-Host " Python $($pyInfo.Ver) download failed, trying next..." -ForegroundColor Yellow
|
|
160
|
-
} finally {
|
|
161
|
-
if (Test-Path $pyExe) { Remove-Item -Force $pyExe -ErrorAction SilentlyContinue }
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
Write-Host "[x] Failed to install Python." -ForegroundColor Red
|
|
167
|
-
Write-Host " Please install Python 3.13+ manually: https://www.python.org/downloads/" -ForegroundColor Gray
|
|
86
|
+
} catch {}
|
|
87
|
+
Write-Host "[x] Failed to install Python. Please install manually: https://www.python.org/downloads/" -ForegroundColor Red
|
|
168
88
|
exit 1
|
|
169
89
|
}
|
|
170
90
|
|
|
171
91
|
# ── Node.js ──────────────────────────────────────────────
|
|
172
92
|
function Check-Node {
|
|
173
|
-
|
|
174
|
-
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
93
|
+
Refresh-Path
|
|
175
94
|
try {
|
|
176
95
|
$nodeVer = (node -v 2>$null)
|
|
177
96
|
if ($nodeVer) {
|
|
@@ -179,204 +98,74 @@ function Check-Node {
|
|
|
179
98
|
if ($major -ge 18) {
|
|
180
99
|
Write-Host "[OK] Node.js $nodeVer found" -ForegroundColor Green
|
|
181
100
|
return $true
|
|
182
|
-
} else {
|
|
183
|
-
Write-Host "[!] Node.js $nodeVer found, but v18+ required" -ForegroundColor Yellow
|
|
184
|
-
return $false
|
|
185
101
|
}
|
|
186
102
|
}
|
|
187
|
-
} catch {
|
|
188
|
-
Write-Host "[!] Node.js not found" -ForegroundColor Yellow
|
|
189
|
-
}
|
|
103
|
+
} catch {}
|
|
190
104
|
return $false
|
|
191
105
|
}
|
|
192
106
|
|
|
193
107
|
function Install-Node {
|
|
194
108
|
Write-Host "[*] Installing Node.js 20 LTS ..." -ForegroundColor Yellow
|
|
195
|
-
|
|
196
109
|
try {
|
|
197
110
|
$null = (winget --version 2>$null)
|
|
198
|
-
Write-Host " Using winget ..." -ForegroundColor Gray
|
|
199
111
|
winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements
|
|
200
112
|
if (Check-Node) { return }
|
|
201
|
-
} catch {
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
# Fallback: download Node.js LTS
|
|
206
|
-
$nodeUrl = "https://nodejs.org/dist/v20.18.0/node-v20.18.0-x64.msi"
|
|
207
|
-
$nodeMsi = Join-Path $env:TEMP "node-installer.msi"
|
|
208
|
-
|
|
209
|
-
try {
|
|
210
|
-
Write-Host " Downloading Node.js 20 LTS ..." -ForegroundColor Gray
|
|
211
|
-
Invoke-WebRequest -Uri $nodeUrl -OutFile $nodeMsi -UseBasicParsing
|
|
212
|
-
|
|
213
|
-
Write-Host " Installing ..." -ForegroundColor Gray
|
|
214
|
-
Start-Process -FilePath msiexec.exe -ArgumentList "/i `"$nodeMsi`" /quiet /norestart" -Wait
|
|
215
|
-
|
|
216
|
-
if (Check-Node) { return }
|
|
217
|
-
} finally {
|
|
218
|
-
if (Test-Path $nodeMsi) { Remove-Item -Force $nodeMsi -ErrorAction SilentlyContinue }
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
Write-Host "[x] Failed to install Node.js." -ForegroundColor Red
|
|
222
|
-
Write-Host " Please install Node.js 18+ manually: https://nodejs.org/" -ForegroundColor Gray
|
|
113
|
+
} catch {}
|
|
114
|
+
Write-Host "[x] Failed to install Node.js. Please install manually: https://nodejs.org/" -ForegroundColor Red
|
|
223
115
|
exit 1
|
|
224
116
|
}
|
|
225
117
|
|
|
226
|
-
# ──
|
|
227
|
-
|
|
228
|
-
Write-Host "[
|
|
229
|
-
|
|
230
|
-
if ($LASTEXITCODE -ne 0) {
|
|
231
|
-
Write-Host "[!] npm install failed, trying with admin..." -ForegroundColor Yellow
|
|
232
|
-
Start-Process npm -ArgumentList "install", "-g", $PKG_NAME -Verb RunAs -Wait
|
|
233
|
-
if ($LASTEXITCODE -ne 0) {
|
|
234
|
-
Write-Host "[x] npm install failed" -ForegroundColor Red
|
|
235
|
-
exit 1
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
Write-Host "[OK] $PKG_NAME installed" -ForegroundColor Green
|
|
118
|
+
# ── Main ─────────────────────────────────────────────────
|
|
119
|
+
if ($DryRun) {
|
|
120
|
+
Write-Host "[OK] Dry run" -ForegroundColor Green
|
|
121
|
+
exit 0
|
|
239
122
|
}
|
|
240
123
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
$pkgDir = Join-Path $npmRoot $PKG_NAME
|
|
246
|
-
$reqFile = Join-Path $pkgDir "requirements.txt"
|
|
247
|
-
|
|
248
|
-
if (-not (Test-Path $reqFile)) {
|
|
249
|
-
if (Test-Path ".\requirements.txt") {
|
|
250
|
-
$reqFile = ".\requirements.txt"
|
|
251
|
-
} else {
|
|
252
|
-
Write-Host "[!] requirements.txt not found, skipping pip install" -ForegroundColor Yellow
|
|
253
|
-
return
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
$venvDir = "$env:USERPROFILE\.myagent\venv"
|
|
258
|
-
$venvPython = Join-Path $venvDir "Scripts\python.exe"
|
|
259
|
-
|
|
260
|
-
Write-Host "[*] Creating virtual environment at $venvDir ..." -ForegroundColor Yellow
|
|
261
|
-
New-Item -ItemType Directory -Path "$env:USERPROFILE\.myagent" -Force | Out-Null
|
|
262
|
-
|
|
263
|
-
# 如果旧 venv 存在且损坏,先删除重建
|
|
264
|
-
if ((Test-Path $venvPython)) {
|
|
265
|
-
try {
|
|
266
|
-
$null = (& $venvPython --version 2>$null)
|
|
267
|
-
} catch {
|
|
268
|
-
Write-Host "[!] 旧虚拟环境损坏,正在重建..." -ForegroundColor Yellow
|
|
269
|
-
Remove-Item -Recurse -Force $venvDir -ErrorAction SilentlyContinue
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
& $pyCmd -m venv $venvDir
|
|
274
|
-
if (-not (Test-Path $venvPython)) {
|
|
275
|
-
Write-Host "[x] 虚拟环境创建失败!Python: $pyCmd" -ForegroundColor Red
|
|
276
|
-
Write-Host " 请手动安装: python -m venv $venvDir" -ForegroundColor Gray
|
|
277
|
-
return
|
|
278
|
-
}
|
|
279
|
-
Write-Host "[OK] Virtual environment created" -ForegroundColor Green
|
|
280
|
-
|
|
281
|
-
Write-Host "[*] Installing Python dependencies into venv ..." -ForegroundColor Yellow
|
|
282
|
-
& $venvPython -m pip install --upgrade pip --quiet 2>$null
|
|
124
|
+
if (-not $NoDeps) {
|
|
125
|
+
if (-not (Check-Python)) { Install-Python }
|
|
126
|
+
if (-not (Check-Node)) { Install-Node }
|
|
127
|
+
}
|
|
283
128
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
129
|
+
Write-Host "[*] Installing $PKG_NAME via npm ..." -ForegroundColor Yellow
|
|
130
|
+
npm install -g $PKG_NAME
|
|
131
|
+
if ($LASTEXITCODE -ne 0) {
|
|
132
|
+
Write-Host "[!] npm install failed, trying with admin..." -ForegroundColor Yellow
|
|
133
|
+
Start-Process npm -ArgumentList "install", "-g", $PKG_NAME -Verb RunAs -Wait
|
|
287
134
|
if ($LASTEXITCODE -ne 0) {
|
|
288
|
-
Write-Host "[
|
|
289
|
-
|
|
135
|
+
Write-Host "[x] npm install failed" -ForegroundColor Red
|
|
136
|
+
exit 1
|
|
290
137
|
}
|
|
291
|
-
if ($LASTEXITCODE -ne 0) {
|
|
292
|
-
Write-Host "[!] 默认源安装失败,尝试阿里云镜像..." -ForegroundColor Yellow
|
|
293
|
-
$aliyunArgs = @("-i", "https://mirrors.aliyun.com/pypi/simple/", "--trusted-host", "mirrors.aliyun.com")
|
|
294
|
-
$pipResult = & $venvPython -m pip install -r $reqFile --disable-pip-version-check @aliyunArgs 2>&1
|
|
295
|
-
}
|
|
296
|
-
if ($LASTEXITCODE -ne 0) {
|
|
297
|
-
Write-Host "[!] 部分依赖安装失败,但核心功能可在启动时自动安装" -ForegroundColor Yellow
|
|
298
|
-
Write-Host " 请运行 'myagent-ai reinstall' 重新安装" -ForegroundColor Gray
|
|
299
|
-
} else {
|
|
300
|
-
Write-Host "[OK] Dependencies installed into venv" -ForegroundColor Green
|
|
301
|
-
}
|
|
302
|
-
Write-Host "[i] Virtual env: $venvDir" -ForegroundColor Gray
|
|
303
|
-
Write-Host "[i] venv will be used automatically on startup" -ForegroundColor Gray
|
|
304
138
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
#
|
|
313
|
-
Refresh-Path
|
|
314
|
-
|
|
315
|
-
# npm 全局命令实际是 .cmd 文件,必须通过 cmd /c 执行
|
|
139
|
+
Write-Host "[OK] $PKG_NAME installed" -ForegroundColor Green
|
|
140
|
+
|
|
141
|
+
# 用 start.js 的 install 命令创建 venv 并安装全部 Python 依赖
|
|
142
|
+
Write-Host "[*] Installing Python dependencies ..." -ForegroundColor Yellow
|
|
143
|
+
try {
|
|
144
|
+
& myagent-ai install
|
|
145
|
+
} catch {
|
|
146
|
+
# myagent-ai 不在 PATH 中,尝试直接调用
|
|
316
147
|
$npmBinDir = ""
|
|
317
|
-
try {
|
|
318
|
-
$npmBinDir = (npm bin -g 2>$null).Trim()
|
|
319
|
-
} catch {}
|
|
320
|
-
|
|
148
|
+
try { $npmBinDir = (npm bin -g 2>$null).Trim() } catch {}
|
|
321
149
|
$cmdPath = ""
|
|
322
150
|
if ($npmBinDir -and (Test-Path "$npmBinDir\myagent-ai.cmd")) {
|
|
323
151
|
$cmdPath = "$npmBinDir\myagent-ai.cmd"
|
|
324
152
|
}
|
|
325
|
-
|
|
326
153
|
if ($cmdPath) {
|
|
327
|
-
|
|
328
|
-
Start-Process cmd -ArgumentList "/c", "`"$cmdPath`" web" -WindowStyle Minimized
|
|
154
|
+
& $cmdPath install
|
|
329
155
|
} else {
|
|
330
|
-
Write-Host "
|
|
331
|
-
Start-Process cmd -ArgumentList "/c", "myagent-ai web" -WindowStyle Minimized
|
|
332
|
-
}
|
|
333
|
-
Write-Host " [OK] MyAgent 已在后台启动" -ForegroundColor Green
|
|
334
|
-
|
|
335
|
-
# 由安装脚本自身轮询服务并打开浏览器(比 start.js 更可靠)
|
|
336
|
-
Write-Host " [i] 等待服务启动..." -ForegroundColor Gray
|
|
337
|
-
$url = "http://127.0.0.1:8767"
|
|
338
|
-
$maxWait = 120 # 最多等 120 秒
|
|
339
|
-
$waited = 0
|
|
340
|
-
while ($waited -lt $maxWait) {
|
|
341
|
-
Start-Sleep -Seconds 2
|
|
342
|
-
$waited += 2
|
|
343
|
-
try {
|
|
344
|
-
$null = Invoke-WebRequest -Uri "$url/api/status" -UseBasicParsing -TimeoutSec 3 -ErrorAction Stop
|
|
345
|
-
Write-Host " [OK] 服务已就绪,正在打开浏览器..." -ForegroundColor Green
|
|
346
|
-
Start-Process $url
|
|
347
|
-
Write-Host " [i] 如果没有自动打开,请访问: $url" -ForegroundColor Cyan
|
|
348
|
-
Write-Host ""
|
|
349
|
-
return
|
|
350
|
-
} catch {
|
|
351
|
-
# 服务还没启动,继续等待
|
|
352
|
-
if ($waited % 10 -eq 0) {
|
|
353
|
-
Write-Host " [i] 等待中... ($waited 秒)" -ForegroundColor Gray
|
|
354
|
-
}
|
|
355
|
-
}
|
|
156
|
+
Write-Host "[i] Please restart terminal and run: myagent-ai install" -ForegroundColor Yellow
|
|
356
157
|
}
|
|
357
|
-
Write-Host " [!] 等待超时" -ForegroundColor Yellow
|
|
358
|
-
Write-Host " [i] 服务可能仍在启动中,请稍等片刻后访问: $url" -ForegroundColor Cyan
|
|
359
|
-
Write-Host ""
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
# ── Main ─────────────────────────────────────────────────
|
|
363
|
-
if ($DryRun) {
|
|
364
|
-
Write-Host "[OK] Dry run" -ForegroundColor Green
|
|
365
|
-
exit 0
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
# Step 1: Dependencies
|
|
369
|
-
if (-not $NoDeps) {
|
|
370
|
-
if (-not (Check-Python)) { Install-Python }
|
|
371
|
-
if (-not (Check-Node)) { Install-Node }
|
|
372
158
|
}
|
|
373
159
|
|
|
374
|
-
|
|
375
|
-
|
|
160
|
+
Write-Host ""
|
|
161
|
+
Write-Host " 安装完成!" -ForegroundColor Green
|
|
162
|
+
Write-Host ""
|
|
376
163
|
|
|
377
|
-
#
|
|
378
|
-
|
|
379
|
-
|
|
164
|
+
# 启动 Web 模式
|
|
165
|
+
Write-Host "[i] Starting myagent-ai web ..." -ForegroundColor Gray
|
|
166
|
+
Refresh-Path
|
|
167
|
+
try {
|
|
168
|
+
Start-Process cmd -ArgumentList "/c", "myagent-ai web" -WindowStyle Minimized
|
|
169
|
+
} catch {
|
|
170
|
+
Write-Host " Please restart terminal and run: myagent-ai web" -ForegroundColor Cyan
|
|
380
171
|
}
|
|
381
|
-
|
|
382
|
-
Show-Guide
|
package/install/install.sh
CHANGED
|
@@ -6,8 +6,7 @@ set -euo pipefail
|
|
|
6
6
|
#
|
|
7
7
|
# 用法:
|
|
8
8
|
# curl -fsSL https://raw.githubusercontent.com/ctz168/myagent/main/install/install.sh | bash
|
|
9
|
-
# curl -fsSL ... | bash -s -- --no-deps #
|
|
10
|
-
# curl -fsSL ... | bash -s -- --dry-run # 预览模式
|
|
9
|
+
# curl -fsSL ... | bash -s -- --no-deps # 跳过系统依赖检查(仅 npm install)
|
|
11
10
|
|
|
12
11
|
BOLD='\033[1m'
|
|
13
12
|
ACCENT='\033[36m'
|
|
@@ -18,34 +17,27 @@ ERROR='\033[31m'
|
|
|
18
17
|
NC='\033[0m'
|
|
19
18
|
|
|
20
19
|
NO_DEPS=false
|
|
21
|
-
DRY_RUN=false
|
|
22
|
-
SCRIPT_URL="https://raw.githubusercontent.com/ctz168/myagent/main/install/install.sh"
|
|
23
20
|
PKG_NAME="myagent-ai"
|
|
24
21
|
PKG_VERSION=""
|
|
25
22
|
|
|
26
|
-
# 动态获取 npm 最新版本号
|
|
27
23
|
fetch_version() {
|
|
28
24
|
PKG_VERSION=""
|
|
29
25
|
local npm_ver
|
|
30
26
|
npm_ver="$(npm view "$PKG_NAME" version 2>/dev/null)" || true
|
|
31
|
-
if [ -n "$npm_ver" ]; then
|
|
32
|
-
PKG_VERSION="$npm_ver"
|
|
33
|
-
fi
|
|
27
|
+
if [ -n "$npm_ver" ]; then PKG_VERSION="$npm_ver"; fi
|
|
34
28
|
}
|
|
35
29
|
|
|
36
30
|
for arg in "$@"; do
|
|
37
31
|
case "$arg" in
|
|
38
32
|
--no-deps) NO_DEPS=true ;;
|
|
39
|
-
--dry-run) DRY_RUN=true ;;
|
|
40
33
|
--help|-h)
|
|
41
34
|
fetch_version
|
|
42
35
|
echo "MyAgent Installer${PKG_VERSION:+ v$PKG_VERSION}"
|
|
43
36
|
echo ""
|
|
44
|
-
echo "Usage: curl -fsSL
|
|
37
|
+
echo "Usage: curl -fsSL <script-url> | bash [-s -- OPTIONS]"
|
|
45
38
|
echo ""
|
|
46
39
|
echo "Options:"
|
|
47
40
|
echo " --no-deps 跳过 Python/Node.js 依赖检查"
|
|
48
|
-
echo " --dry-run 预览安装过程,不实际执行"
|
|
49
41
|
echo ""
|
|
50
42
|
echo "安装完成后运行 myagent-ai 启动"
|
|
51
43
|
exit 0
|
|
@@ -71,176 +63,77 @@ detect_os() {
|
|
|
71
63
|
esac
|
|
72
64
|
}
|
|
73
65
|
|
|
74
|
-
# 尝试获取最新版本(获取失败则不显示版本号)
|
|
75
66
|
fetch_version
|
|
76
|
-
|
|
77
67
|
OS="$(detect_os)"
|
|
78
68
|
echo ""
|
|
79
69
|
echo -e " ${BOLD}${ACCENT}MyAgent${NC} Installer${PKG_VERSION:+ v$PKG_VERSION}"
|
|
80
70
|
echo ""
|
|
81
71
|
success "$OS detected"
|
|
82
72
|
|
|
83
|
-
if $DRY_RUN; then
|
|
84
|
-
success "Dry run mode"
|
|
85
|
-
info "Will: check deps -> npm install -g $PKG_NAME -> pip install requirements"
|
|
86
|
-
exit 0
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
73
|
# ── Python ────────────────────────────────────────────────
|
|
90
|
-
# 记录已找到的 Python 命令,供后续步骤使用
|
|
91
|
-
_PYTHON_CMD=""
|
|
92
|
-
|
|
93
74
|
check_python() {
|
|
94
|
-
# 刷新命令缓存(关键:安装新软件后 bash 会缓存旧的查找结果)
|
|
95
75
|
hash -r 2>/dev/null || true
|
|
96
|
-
|
|
97
|
-
# 按优先级尝试多个 Python 命令(包括版本号后缀的)
|
|
98
76
|
local py_cmd=""
|
|
99
77
|
for cmd in python3 python3.14 python3.13 python; do
|
|
100
|
-
if command -v "$cmd" &>/dev/null; then
|
|
101
|
-
py_cmd="$cmd"
|
|
102
|
-
break
|
|
103
|
-
fi
|
|
78
|
+
if command -v "$cmd" &>/dev/null; then py_cmd="$cmd"; break; fi
|
|
104
79
|
done
|
|
105
|
-
|
|
106
|
-
if [ -z "$py_cmd" ]; then
|
|
107
|
-
return 1
|
|
108
|
-
fi
|
|
109
|
-
|
|
110
|
-
# 检查版本
|
|
80
|
+
if [ -z "$py_cmd" ]; then return 1; fi
|
|
111
81
|
local ver
|
|
112
82
|
ver="$($py_cmd -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null)" || return 1
|
|
113
83
|
local major minor
|
|
114
84
|
major="$(echo "$ver" | cut -d. -f1)"
|
|
115
85
|
minor="$(echo "$ver" | cut -d. -f2)"
|
|
116
86
|
if [ "$major" -ge 3 ] && [ "$minor" -ge 13 ]; then
|
|
117
|
-
_PYTHON_CMD="$py_cmd"
|
|
118
87
|
success "Python $ver ($py_cmd)"
|
|
119
88
|
return 0
|
|
120
89
|
fi
|
|
121
|
-
warn "Python $ver found, upgrading to 3.13+ ..."
|
|
122
|
-
# 仍然记录当前可用的 Python(即使版本低,也总比没有好)
|
|
123
|
-
_PYTHON_CMD="$py_cmd"
|
|
124
|
-
return 1
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
# 获取可用的 Python 命令(安装后也会重新查找)
|
|
128
|
-
get_python_cmd() {
|
|
129
|
-
if [ -n "$_PYTHON_CMD" ] && command -v "$_PYTHON_CMD" &>/dev/null; then
|
|
130
|
-
echo "$_PYTHON_CMD"
|
|
131
|
-
return 0
|
|
132
|
-
fi
|
|
133
|
-
hash -r 2>/dev/null || true
|
|
134
|
-
for cmd in python3 python3.14 python3.13 python; do
|
|
135
|
-
if command -v "$cmd" &>/dev/null; then
|
|
136
|
-
_PYTHON_CMD="$cmd"
|
|
137
|
-
echo "$cmd"
|
|
138
|
-
return 0
|
|
139
|
-
fi
|
|
140
|
-
done
|
|
141
|
-
echo ""
|
|
142
90
|
return 1
|
|
143
91
|
}
|
|
144
92
|
|
|
145
93
|
install_python() {
|
|
146
94
|
step "Installing Python 3.13+ ..."
|
|
147
|
-
local installed=false
|
|
148
|
-
|
|
149
95
|
if [ "$OS" = "macos" ]; then
|
|
150
96
|
if command -v brew &>/dev/null; then
|
|
151
|
-
info "Using Homebrew ..."
|
|
152
|
-
# 尝试多个版本,优先 3.13+
|
|
153
97
|
for py_ver in 3.13 3.14; do
|
|
154
|
-
brew install "python@${py_ver}" 2>/dev/null
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
brew_prefix="$(brew --prefix "python@${py_ver}")"
|
|
159
|
-
export PATH="${brew_prefix}/bin:$PATH"
|
|
160
|
-
hash -r
|
|
161
|
-
sleep 1
|
|
162
|
-
if check_python; then return 0; fi
|
|
163
|
-
# brew 已安装但 python3 软链接可能不存在
|
|
164
|
-
local brew_py="${brew_prefix}/bin/python3"
|
|
165
|
-
if [ -x "$brew_py" ]; then
|
|
166
|
-
_PYTHON_CMD="$brew_py"
|
|
167
|
-
success "Python found at $brew_py"
|
|
168
|
-
return 0
|
|
98
|
+
if brew install "python@${py_ver}" 2>/dev/null; then
|
|
99
|
+
export PATH="$(brew --prefix "python@${py_ver}")/bin:$PATH"
|
|
100
|
+
hash -r
|
|
101
|
+
check_python && return 0
|
|
169
102
|
fi
|
|
170
|
-
|
|
171
|
-
for ver in 3.14 3.13; do
|
|
172
|
-
brew_py="${brew_prefix}/bin/python${ver}"
|
|
173
|
-
if [ -x "$brew_py" ]; then
|
|
174
|
-
_PYTHON_CMD="$brew_py"
|
|
175
|
-
success "Python found at $brew_py"
|
|
176
|
-
return 0
|
|
177
|
-
fi
|
|
178
|
-
done
|
|
179
|
-
_PYTHON_CMD="${brew_prefix}/bin/python3"
|
|
180
|
-
warn "Python 已通过 Homebrew 安装,但 python3 命令暂不可用"
|
|
181
|
-
info "请重启终端或运行: export PATH=\"${brew_prefix}/bin:\$PATH\""
|
|
182
|
-
return 0
|
|
183
|
-
fi
|
|
184
|
-
fi
|
|
185
|
-
# 仅在 brew 未安装时才从 python.org 下载
|
|
186
|
-
if ! $installed; then
|
|
187
|
-
info "Downloading Python 3.13 ..."
|
|
188
|
-
curl -fsSL -o /tmp/python.pkg "https://www.python.org/ftp/python/3.13.3/python-3.13.3-macos11.pkg" 2>/dev/null || \
|
|
189
|
-
curl -fsSL -o /tmp/python.pkg "https://www.python.org/ftp/python/3.14.0/python-3.14.0-macos11.pkg"
|
|
190
|
-
sudo installer -pkg /tmp/python.pkg -target /
|
|
191
|
-
rm -f /tmp/python.pkg
|
|
192
|
-
export PATH="/Library/Frameworks/Python.framework/Versions/3.13/bin:$PATH"
|
|
193
|
-
hash -r
|
|
194
|
-
if check_python; then return 0; fi
|
|
103
|
+
done
|
|
195
104
|
fi
|
|
105
|
+
curl -fsSL -o /tmp/python.pkg "https://www.python.org/ftp/python/3.13.3/python-3.13.3-macos11.pkg" 2>/dev/null || \
|
|
106
|
+
curl -fsSL -o /tmp/python.pkg "https://www.python.org/ftp/python/3.14.0/python-3.14.0-macos11.pkg"
|
|
107
|
+
sudo installer -pkg /tmp/python.pkg -target /
|
|
108
|
+
rm -f /tmp/python.pkg
|
|
109
|
+
export PATH="/Library/Frameworks/Python.framework/Versions/3.13/bin:$PATH"
|
|
110
|
+
hash -r
|
|
111
|
+
check_python && return 0
|
|
196
112
|
return 1
|
|
197
113
|
fi
|
|
198
|
-
|
|
199
114
|
if [ "$OS" = "linux" ]; then
|
|
200
115
|
if command -v apt-get &>/dev/null; then
|
|
201
|
-
info "Using apt ..."
|
|
202
116
|
sudo apt-get update -qq
|
|
203
|
-
# 尝试安装 3.13+,回退到默认 python3
|
|
204
117
|
sudo apt-get install -y python3.13 python3.13-venv python3-pip 2>/dev/null || \
|
|
205
118
|
sudo apt-get install -y python3.14 python3.14-venv python3-pip 2>/dev/null || \
|
|
206
119
|
sudo apt-get install -y python3 python3-venv python3-pip
|
|
207
120
|
hash -r
|
|
208
|
-
|
|
209
|
-
for ver in 3.14 3.13; do
|
|
210
|
-
if command -v "python${ver}" &>/dev/null; then
|
|
211
|
-
_PYTHON_CMD="python${ver}"
|
|
212
|
-
success "Python found as python${ver}"
|
|
213
|
-
return 0
|
|
214
|
-
fi
|
|
215
|
-
done
|
|
216
|
-
return 1
|
|
121
|
+
check_python && return 0
|
|
217
122
|
fi
|
|
218
123
|
if command -v dnf &>/dev/null; then
|
|
219
|
-
info "Using dnf ..."
|
|
220
124
|
sudo dnf install -y python3.13 2>/dev/null || sudo dnf install -y python3
|
|
221
|
-
hash -r
|
|
222
|
-
if check_python; then return 0; fi
|
|
223
|
-
return 1
|
|
125
|
+
hash -r; check_python && return 0
|
|
224
126
|
fi
|
|
225
127
|
if command -v pacman &>/dev/null; then
|
|
226
|
-
info "Using pacman ..."
|
|
227
128
|
sudo pacman -S --noconfirm python python-pip
|
|
228
|
-
hash -r
|
|
229
|
-
if check_python; then return 0; fi
|
|
230
|
-
return 1
|
|
129
|
+
hash -r; check_python && return 0
|
|
231
130
|
fi
|
|
232
131
|
if command -v apk &>/dev/null; then
|
|
233
|
-
info "Using apk ..."
|
|
234
132
|
sudo apk add python3 py3-pip
|
|
235
|
-
hash -r
|
|
236
|
-
if check_python; then return 0; fi
|
|
237
|
-
return 1
|
|
133
|
+
hash -r; check_python && return 0
|
|
238
134
|
fi
|
|
239
135
|
fi
|
|
240
|
-
|
|
241
136
|
err "Failed to install Python. Please install Python 3.13+ manually."
|
|
242
|
-
info " macOS: https://www.python.org/downloads/"
|
|
243
|
-
info " Linux: https://wiki.python.org/moin/BeginnersGuide/Download"
|
|
244
137
|
exit 1
|
|
245
138
|
}
|
|
246
139
|
|
|
@@ -254,325 +147,76 @@ check_node() {
|
|
|
254
147
|
success "Node.js $(node -v)"
|
|
255
148
|
return 0
|
|
256
149
|
fi
|
|
257
|
-
warn "Node.js $(node -v) found, but v18+ required"
|
|
258
150
|
return 1
|
|
259
151
|
}
|
|
260
152
|
|
|
261
153
|
install_node() {
|
|
262
154
|
step "Installing Node.js 20 LTS ..."
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
info "Using Homebrew ..."
|
|
267
|
-
brew install node@20 || brew install node
|
|
268
|
-
export PATH="$(brew --prefix node)/bin:$PATH"
|
|
269
|
-
hash -r
|
|
270
|
-
if check_node; then return 0; fi
|
|
271
|
-
fi
|
|
155
|
+
if [ "$OS" = "macos" ] && command -v brew &>/dev/null; then
|
|
156
|
+
brew install node@20 || brew install node
|
|
157
|
+
hash -r; check_node && return 0
|
|
272
158
|
fi
|
|
273
|
-
|
|
274
|
-
# Try fnm
|
|
275
159
|
if command -v fnm &>/dev/null; then
|
|
276
|
-
|
|
277
|
-
fnm install 20
|
|
278
|
-
eval "$(fnm env)"
|
|
279
|
-
hash -r
|
|
280
|
-
if check_node; then return 0; fi
|
|
160
|
+
fnm install 20; eval "$(fnm env)"; hash -r; check_node && return 0
|
|
281
161
|
fi
|
|
282
|
-
|
|
283
|
-
# Try nvm
|
|
284
162
|
if [ -s "$HOME/.nvm/nvm.sh" ]; then
|
|
285
|
-
|
|
286
|
-
. "$HOME/.nvm/nvm.sh"
|
|
287
|
-
nvm install 20
|
|
288
|
-
hash -r
|
|
289
|
-
if check_node; then return 0; fi
|
|
290
|
-
fi
|
|
291
|
-
|
|
292
|
-
# Fallback: NodeSource
|
|
293
|
-
if [ "$OS" = "linux" ]; then
|
|
294
|
-
if command -v apt-get &>/dev/null; then
|
|
295
|
-
info "Using NodeSource ..."
|
|
296
|
-
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
297
|
-
sudo apt-get install -y nodejs
|
|
298
|
-
hash -r
|
|
299
|
-
if check_node; then return 0; fi
|
|
300
|
-
return 1
|
|
301
|
-
fi
|
|
302
|
-
if command -v dnf &>/dev/null; then
|
|
303
|
-
info "Using dnf ..."
|
|
304
|
-
sudo dnf install -y nodejs npm
|
|
305
|
-
hash -r
|
|
306
|
-
if check_node; then return 0; fi
|
|
307
|
-
return 1
|
|
308
|
-
fi
|
|
163
|
+
. "$HOME/.nvm/nvm.sh"; nvm install 20; hash -r; check_node && return 0
|
|
309
164
|
fi
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
curl -fsSL https://fnm.vercel.app/install | bash
|
|
315
|
-
export PATH="$HOME/.local/share/fnm:$PATH"
|
|
316
|
-
eval "$(fnm env)"
|
|
165
|
+
if [ "$OS" = "linux" ] && command -v apt-get &>/dev/null; then
|
|
166
|
+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
167
|
+
sudo apt-get install -y nodejs
|
|
168
|
+
hash -r; check_node && return 0
|
|
317
169
|
fi
|
|
318
|
-
fnm install 20
|
|
319
|
-
hash -r
|
|
320
|
-
if check_node; then return 0; fi
|
|
321
|
-
|
|
322
170
|
err "Failed to install Node.js. Please install Node.js 18+ manually."
|
|
323
|
-
info " https://nodejs.org/"
|
|
324
171
|
exit 1
|
|
325
172
|
}
|
|
326
173
|
|
|
327
|
-
# ── pip install (处理 PEP668) ──────────────────────
|
|
328
|
-
pip_install() {
|
|
329
|
-
local req_file="$1"
|
|
330
|
-
# 尝试多种方式安装,兼容 PEP668 限制
|
|
331
|
-
pip3 install -r "$req_file" --break-system-packages 2>/dev/null || \
|
|
332
|
-
pip3 install -r "$req_file" 2>/dev/null || \
|
|
333
|
-
pip install -r "$req_file" --break-system-packages 2>/dev/null || \
|
|
334
|
-
pip install -r "$req_file" 2>/dev/null || \
|
|
335
|
-
{
|
|
336
|
-
warn "pip install 失败 (可能受 PEP668 限制)"
|
|
337
|
-
info "尝试使用 venv 安装..."
|
|
338
|
-
local venv_dir="$HOME/.myagent/venv"
|
|
339
|
-
python3 -m venv "$venv_dir" 2>/dev/null
|
|
340
|
-
if [ -f "$venv_dir/bin/pip" ]; then
|
|
341
|
-
"$venv_dir/bin/pip" install -r "$req_file"
|
|
342
|
-
success "已安装到虚拟环境 $venv_dir"
|
|
343
|
-
info "启动时请使用: $venv_dir/bin/python main.py --web"
|
|
344
|
-
return 0
|
|
345
|
-
fi
|
|
346
|
-
err "所有安装方式均失败"
|
|
347
|
-
info "请手动安装: pip3 install -r $req_file --break-system-packages"
|
|
348
|
-
info "或使用虚拟环境: python3 -m venv venv && source venv/bin/activate && pip install -r $req_file"
|
|
349
|
-
return 1
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
# ── Install MyAgent via npm ──────────────────────────────
|
|
354
|
-
install_myagent() {
|
|
355
|
-
step "Installing $PKG_NAME ..."
|
|
356
|
-
npm install -g "$PKG_NAME"
|
|
357
|
-
if [ $? -ne 0 ]; then
|
|
358
|
-
err "npm install failed"
|
|
359
|
-
info "可能需要 sudo: sudo npm install -g $PKG_NAME"
|
|
360
|
-
exit 1
|
|
361
|
-
fi
|
|
362
|
-
success "$PKG_NAME installed"
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
# ── 确保 venv 模块可用 ──────────────────────────────────
|
|
366
|
-
# 在 Debian/Ubuntu 上,python3.xx-venv 需要单独安装
|
|
367
|
-
ensure_venv_module() {
|
|
368
|
-
local py_cmd="$1"
|
|
369
|
-
# 先测试 venv 是否可用
|
|
370
|
-
if "$py_cmd" -c "import venv" 2>/dev/null; then
|
|
371
|
-
return 0
|
|
372
|
-
fi
|
|
373
|
-
|
|
374
|
-
warn "venv 模块不可用,正在自动安装..."
|
|
375
|
-
|
|
376
|
-
if [ "$OS" = "linux" ]; then
|
|
377
|
-
if command -v apt-get &>/dev/null; then
|
|
378
|
-
# 获取 Python 版本号,安装对应的 -venv 包
|
|
379
|
-
local py_ver
|
|
380
|
-
py_ver="$($py_cmd -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null)" || ""
|
|
381
|
-
if [ -n "$py_ver" ]; then
|
|
382
|
-
step "安装 python${py_ver}-venv ..."
|
|
383
|
-
# root 用户不需要 sudo
|
|
384
|
-
if [ "$(id -u)" -eq 0 ]; then
|
|
385
|
-
apt-get install -y "python${py_ver}-venv" && {
|
|
386
|
-
success "python${py_ver}-venv 已安装"
|
|
387
|
-
return 0
|
|
388
|
-
}
|
|
389
|
-
else
|
|
390
|
-
sudo apt-get install -y "python${py_ver}-venv" && {
|
|
391
|
-
success "python${py_ver}-venv 已安装"
|
|
392
|
-
return 0
|
|
393
|
-
}
|
|
394
|
-
fi
|
|
395
|
-
fi
|
|
396
|
-
# 回退:尝试常见版本
|
|
397
|
-
for ver in 3.13 3.14 3; do
|
|
398
|
-
step "尝试安装 python${ver}-venv ..."
|
|
399
|
-
if [ "$(id -u)" -eq 0 ]; then
|
|
400
|
-
apt-get install -y "python${ver}-venv" && {
|
|
401
|
-
success "python${ver}-venv 已安装"
|
|
402
|
-
return 0
|
|
403
|
-
}
|
|
404
|
-
else
|
|
405
|
-
sudo apt-get install -y "python${ver}-venv" && {
|
|
406
|
-
success "python${ver}-venv 已安装"
|
|
407
|
-
return 0
|
|
408
|
-
}
|
|
409
|
-
fi
|
|
410
|
-
done
|
|
411
|
-
fi
|
|
412
|
-
if command -v dnf &>/dev/null; then
|
|
413
|
-
if [ "$(id -u)" -eq 0 ]; then
|
|
414
|
-
dnf install -y python3-venv 2>/dev/null
|
|
415
|
-
else
|
|
416
|
-
sudo dnf install -y python3-venv 2>/dev/null
|
|
417
|
-
fi
|
|
418
|
-
return 0
|
|
419
|
-
fi
|
|
420
|
-
if command -v apk &>/dev/null; then
|
|
421
|
-
if [ "$(id -u)" -eq 0 ]; then
|
|
422
|
-
apk add py3-virtualenv
|
|
423
|
-
else
|
|
424
|
-
sudo apk add py3-virtualenv
|
|
425
|
-
fi
|
|
426
|
-
return 0
|
|
427
|
-
fi
|
|
428
|
-
fi
|
|
429
|
-
|
|
430
|
-
if [ "$OS" = "macos" ]; then
|
|
431
|
-
warn "macOS 上 venv 不可用,请重新安装 Python"
|
|
432
|
-
return 1
|
|
433
|
-
fi
|
|
434
|
-
|
|
435
|
-
err "无法自动安装 venv 模块"
|
|
436
|
-
info "请手动运行: sudo apt install python3-venv"
|
|
437
|
-
return 1
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
# ── Install Python dependencies (使用独立虚拟环境) ──
|
|
441
|
-
install_python_deps() {
|
|
442
|
-
local pkg_dir
|
|
443
|
-
pkg_dir="$(npm root -g)/$PKG_NAME"
|
|
444
|
-
local req_file="$pkg_dir/requirements.txt"
|
|
445
|
-
|
|
446
|
-
if [ ! -f "$req_file" ]; then
|
|
447
|
-
if [ -f "./requirements.txt" ]; then
|
|
448
|
-
req_file="./requirements.txt"
|
|
449
|
-
else
|
|
450
|
-
warn "requirements.txt not found, skipping pip install"
|
|
451
|
-
return
|
|
452
|
-
fi
|
|
453
|
-
fi
|
|
454
|
-
|
|
455
|
-
local py_cmd
|
|
456
|
-
py_cmd="$(get_python_cmd)"
|
|
457
|
-
if [ -z "$py_cmd" ]; then
|
|
458
|
-
err "Python not found, cannot install dependencies"
|
|
459
|
-
return 1
|
|
460
|
-
fi
|
|
461
|
-
|
|
462
|
-
local venv_dir="$HOME/.myagent/venv"
|
|
463
|
-
|
|
464
|
-
step "Creating virtual environment at $venv_dir ..."
|
|
465
|
-
mkdir -p "$HOME/.myagent"
|
|
466
|
-
|
|
467
|
-
# 确保 venv 模块可用(自动安装 python3.xx-venv)
|
|
468
|
-
ensure_venv_module "$py_cmd" || {
|
|
469
|
-
err "无法创建虚拟环境,venv 模块不可用"
|
|
470
|
-
info "请手动运行: sudo apt install python3-venv"
|
|
471
|
-
info "然后重新运行: myagent-ai reinstall"
|
|
472
|
-
return 1
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
"$py_cmd" -m venv "$venv_dir"
|
|
476
|
-
success "Virtual environment created"}
|
|
477
|
-
|
|
478
|
-
step "Installing Python dependencies into venv ..."
|
|
479
|
-
"$venv_dir/bin/pip" install --upgrade pip --quiet 2>/dev/null || true
|
|
480
|
-
|
|
481
|
-
# Linux: 预装 evdev 预编译包,避免 pynput 安装时编译失败(需要 linux-headers)
|
|
482
|
-
# evdev-binary 是预编译版本,无需编译;如果安装失败也不影响核心功能
|
|
483
|
-
if [ "$OS" = "linux" ]; then
|
|
484
|
-
"$venv_dir/bin/pip" install evdev-binary --disable-pip-version-check --quiet 2>/dev/null || true
|
|
485
|
-
fi
|
|
486
|
-
|
|
487
|
-
# 尝试使用清华镜像安装(国内用户更快)
|
|
488
|
-
if "$venv_dir/bin/pip" install -r "$req_file" --disable-pip-version-check \
|
|
489
|
-
-i https://pypi.tuna.tsinghua.edu.cn/simple \
|
|
490
|
-
--trusted-host pypi.tuna.tsinghua.edu.cn 2>/dev/null; then
|
|
491
|
-
success "Dependencies installed into venv (清华镜像)"
|
|
492
|
-
elif "$venv_dir/bin/pip" install -r "$req_file" --disable-pip-version-check 2>/dev/null; then
|
|
493
|
-
success "Dependencies installed into venv"
|
|
494
|
-
elif "$venv_dir/bin/pip" install -r "$req_file" --disable-pip-version-check \
|
|
495
|
-
-i https://mirrors.aliyun.com/pypi/simple/ \
|
|
496
|
-
--trusted-host mirrors.aliyun.com 2>/dev/null; then
|
|
497
|
-
success "Dependencies installed into venv (阿里云镜像)"
|
|
498
|
-
else
|
|
499
|
-
warn "部分依赖安装失败,但核心功能可在启动时自动安装"
|
|
500
|
-
info "请运行 'myagent-ai reinstall' 重新安装"
|
|
501
|
-
fi
|
|
502
|
-
info "虚拟环境: $venv_dir"
|
|
503
|
-
info "启动时自动使用 venv,无需手动激活"
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
# ── 安装完成:直接启动 ───────────────────────────────
|
|
507
|
-
post_install() {
|
|
508
|
-
echo ""
|
|
509
|
-
echo -e " ${BOLD}${SUCCESS}安装完成!正在启动 MyAgent...${NC}"
|
|
510
|
-
echo ""
|
|
511
|
-
|
|
512
|
-
# 直接启动 Web 模式,浏览器会自动打开配置向导
|
|
513
|
-
# 使用 nohup 在后台运行,不阻塞终端
|
|
514
|
-
if command -v myagent-ai &>/dev/null; then
|
|
515
|
-
nohup myagent-ai web > /dev/null 2>&1 &
|
|
516
|
-
echo -e " ${SUCCESS}[✓]${NC} MyAgent 已在后台启动"
|
|
517
|
-
else
|
|
518
|
-
# myagent-ai 不在 PATH 中,尝试通过 npm 全局目录启动
|
|
519
|
-
local npm_bin
|
|
520
|
-
npm_bin="$(npm bin -g 2>/dev/null)/myagent-ai"
|
|
521
|
-
if [ -x "$npm_bin" ]; then
|
|
522
|
-
nohup "$npm_bin" web > /dev/null 2>&1 &
|
|
523
|
-
echo -e " ${SUCCESS}[✓]${NC} MyAgent 已在后台启动"
|
|
524
|
-
else
|
|
525
|
-
echo -e " ${WARN}[!]${NC} 启动命令未找到,请重新打开终端后运行:"
|
|
526
|
-
echo -e " ${ACCENT}myagent-ai web${NC}"
|
|
527
|
-
echo ""
|
|
528
|
-
return
|
|
529
|
-
fi
|
|
530
|
-
fi
|
|
531
|
-
|
|
532
|
-
# 由安装脚本自身轮询服务并打开浏览器(比 start.js 更可靠)
|
|
533
|
-
local url="http://127.0.0.1:8767"
|
|
534
|
-
local max_wait=120
|
|
535
|
-
local waited=0
|
|
536
|
-
|
|
537
|
-
echo -e " ${INFO}[i]${NC} 等待服务启动..."
|
|
538
|
-
while [ $waited -lt $max_wait ]; do
|
|
539
|
-
sleep 2
|
|
540
|
-
waited=$((waited + 2))
|
|
541
|
-
if curl -sf "$url/api/status" > /dev/null 2>&1; then
|
|
542
|
-
echo -e " ${SUCCESS}[✓]${NC} 服务已就绪,正在打开浏览器..."
|
|
543
|
-
# 跨平台打开浏览器
|
|
544
|
-
if [ "$OS" = "macos" ]; then
|
|
545
|
-
open "$url" 2>/dev/null || true
|
|
546
|
-
elif [ "$OS" = "linux" ]; then
|
|
547
|
-
xdg-open "$url" 2>/dev/null || sensible-browser "$url" 2>/dev/null || true
|
|
548
|
-
fi
|
|
549
|
-
echo -e " ${INFO}[i]${NC} 如果没有自动打开,请访问: ${ACCENT}$url${NC}"
|
|
550
|
-
echo ""
|
|
551
|
-
return
|
|
552
|
-
fi
|
|
553
|
-
if [ $((waited % 10)) -eq 0 ]; then
|
|
554
|
-
echo -e " ${INFO}[i]${NC} 等待中... ($waited 秒)"
|
|
555
|
-
fi
|
|
556
|
-
done
|
|
557
|
-
echo -e " ${WARN}[!]${NC} 等待超时"
|
|
558
|
-
echo -e " ${INFO}[i]${NC} 服务可能仍在启动中,请稍等片刻后访问: ${ACCENT}$url${NC}"
|
|
559
|
-
echo ""
|
|
560
|
-
}
|
|
561
|
-
|
|
562
174
|
# ── Main ─────────────────────────────────────────────────
|
|
563
175
|
if ! $NO_DEPS; then
|
|
564
176
|
check_python || install_python
|
|
565
177
|
check_node || install_node
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
step "Installing $PKG_NAME via npm ..."
|
|
181
|
+
npm install -g "$PKG_NAME"
|
|
182
|
+
if [ $? -ne 0 ]; then
|
|
183
|
+
err "npm install failed"
|
|
184
|
+
info "可能需要 sudo: sudo npm install -g $PKG_NAME"
|
|
185
|
+
exit 1
|
|
186
|
+
fi
|
|
187
|
+
success "$PKG_NAME installed"
|
|
188
|
+
|
|
189
|
+
# 用 start.js 的 install 命令创建 venv 并安装全部 Python 依赖
|
|
190
|
+
step "Installing Python dependencies ..."
|
|
191
|
+
if command -v myagent-ai &>/dev/null; then
|
|
192
|
+
myagent-ai install
|
|
193
|
+
else
|
|
194
|
+
# myagent-ai 不在 PATH 中,尝试直接调用
|
|
195
|
+
local npm_bin
|
|
196
|
+
npm_bin="$(npm bin -g 2>/dev/null)/myagent-ai"
|
|
197
|
+
if [ -x "$npm_bin" ]; then
|
|
198
|
+
"$npm_bin" install
|
|
199
|
+
else
|
|
200
|
+
err "myagent-ai 命令未找到,请重新打开终端后运行: myagent-ai install"
|
|
201
|
+
exit 1
|
|
569
202
|
fi
|
|
570
203
|
fi
|
|
571
204
|
|
|
572
|
-
|
|
205
|
+
echo ""
|
|
206
|
+
echo -e " ${BOLD}${SUCCESS}安装完成!${NC}"
|
|
207
|
+
echo ""
|
|
573
208
|
|
|
574
|
-
|
|
575
|
-
|
|
209
|
+
# 启动 Web 模式
|
|
210
|
+
if command -v myagent-ai &>/dev/null; then
|
|
211
|
+
info "启动中: myagent-ai web"
|
|
212
|
+
myagent-ai web
|
|
213
|
+
else
|
|
214
|
+
local npm_bin
|
|
215
|
+
npm_bin="$(npm bin -g 2>/dev/null)/myagent-ai"
|
|
216
|
+
if [ -x "$npm_bin" ]; then
|
|
217
|
+
info "启动中: $npm_bin web"
|
|
218
|
+
"$npm_bin" web
|
|
219
|
+
else
|
|
220
|
+
echo -e " 请重新打开终端后运行: ${ACCENT}myagent-ai web${NC}"
|
|
221
|
+
fi
|
|
576
222
|
fi
|
|
577
|
-
|
|
578
|
-
post_install
|