ai-helper-agent 1.5.2 → 1.6.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-helper-agent",
3
- "version": "1.5.2",
3
+ "version": "1.6.1",
4
4
  "description": "AI Helper 代理服务 - 为 Chrome 扩展提供本地文件读写和系统命令执行能力",
5
5
  "type": "module",
6
6
  "main": "./src/server.js",
package/src/executor.js CHANGED
@@ -1,8 +1,56 @@
1
1
  // agent/src/executor.js - 命令执行器(child_process + 流式输出)
2
2
  import { spawn } from 'child_process';
3
3
  import crypto from 'crypto';
4
+ import os from 'os';
4
5
  import { loadConfig } from './config.js';
5
6
 
7
+ function getShellForExec() {
8
+ const platform = os.platform();
9
+ const envShell = process.env.SHELL || process.env.COMSPEC || '';
10
+
11
+ if (platform === 'win32') {
12
+ if (envShell.toLowerCase().includes('bash')) {
13
+ return { shell: envShell, args: ['-c'] };
14
+ } else if (envShell.toLowerCase().includes('powershell')) {
15
+ return { shell: envShell, args: ['-Command'] };
16
+ } else if (envShell.toLowerCase().includes('cmd')) {
17
+ return { shell: envShell, args: ['/c'] };
18
+ } else {
19
+ const gitBashPaths = [
20
+ 'C:\\Program Files\\Git\\bin\\bash.exe',
21
+ 'C:\\Program Files (x86)\\Git\\bin\\bash.exe',
22
+ `${process.env.USERPROFILE}\\AppData\\Local\\Programs\\Git\\bin\\bash.exe`,
23
+ ];
24
+ for (const path of gitBashPaths) {
25
+ try {
26
+ if (require('fs').existsSync(path)) {
27
+ return { shell: path, args: ['-c'] };
28
+ }
29
+ } catch {}
30
+ }
31
+ return { shell: 'cmd.exe', args: ['/c'] };
32
+ }
33
+ }
34
+
35
+ if (platform === 'darwin') {
36
+ if (envShell.toLowerCase().includes('zsh')) {
37
+ return { shell: envShell, args: ['-c'] };
38
+ } else if (envShell.toLowerCase().includes('bash')) {
39
+ return { shell: envShell, args: ['-c'] };
40
+ }
41
+ return { shell: '/bin/zsh', args: ['-c'] };
42
+ }
43
+
44
+ if (envShell.toLowerCase().includes('bash')) {
45
+ return { shell: envShell, args: ['-c'] };
46
+ } else if (envShell.toLowerCase().includes('zsh')) {
47
+ return { shell: envShell, args: ['-c'] };
48
+ } else if (envShell.toLowerCase().includes('fish')) {
49
+ return { shell: envShell, args: ['-c'] };
50
+ }
51
+ return { shell: '/bin/bash', args: ['-c'] };
52
+ }
53
+
6
54
  // 运行中的进程映射:execId → { process, wsClients: Set, timeoutId, forceKillId }
7
55
  const runningProcesses = new Map();
8
56
 
@@ -62,7 +110,8 @@ function executeCommand(command, cwd, wsClient, onComplete, collectOutput = fals
62
110
  const execId = generateExecId();
63
111
  const timeout = config.commandTimeout || 300000;
64
112
 
65
- const proc = spawn('sh', ['-c', command], {
113
+ const { shell, args } = getShellForExec();
114
+ const proc = spawn(shell, [...args, command], {
66
115
  cwd: workdir,
67
116
  env: buildSafeEnv(),
68
117
  stdio: ['ignore', 'pipe', 'pipe'],
package/src/server.js CHANGED
@@ -51,7 +51,53 @@ const MAX_LOG_QUERY_LIMIT = 1000; // 日志查询最大条数
51
51
  const PID_FILE = join(homedir(), '.ai-helper-agent', 'agent.pid');
52
52
  const DEFAULT_MAX_SIZE = 50 * 1024 * 1024; // 文件默认大小限制
53
53
 
54
- // 平台信息(启动时检测一次)
54
+ function detectShell() {
55
+ const platform = os.platform();
56
+ const envShell = process.env.SHELL || process.env.COMSPEC || '';
57
+
58
+ if (platform === 'win32') {
59
+ if (envShell.toLowerCase().includes('bash')) {
60
+ return envShell;
61
+ } else if (envShell.toLowerCase().includes('powershell')) {
62
+ return envShell;
63
+ } else if (envShell.toLowerCase().includes('cmd')) {
64
+ return envShell;
65
+ } else {
66
+ const gitBashPaths = [
67
+ 'C:\\Program Files\\Git\\bin\\bash.exe',
68
+ 'C:\\Program Files (x86)\\Git\\bin\\bash.exe',
69
+ `${process.env.USERPROFILE}\\AppData\\Local\\Programs\\Git\\bin\\bash.exe`,
70
+ ];
71
+ for (const path of gitBashPaths) {
72
+ try {
73
+ if (require('fs').existsSync(path)) {
74
+ return path;
75
+ }
76
+ } catch {}
77
+ }
78
+ return 'cmd.exe';
79
+ }
80
+ }
81
+
82
+ if (platform === 'darwin') {
83
+ if (envShell.toLowerCase().includes('zsh')) {
84
+ return envShell;
85
+ } else if (envShell.toLowerCase().includes('bash')) {
86
+ return envShell;
87
+ }
88
+ return '/bin/zsh';
89
+ }
90
+
91
+ if (envShell.toLowerCase().includes('bash')) {
92
+ return envShell;
93
+ } else if (envShell.toLowerCase().includes('zsh')) {
94
+ return envShell;
95
+ } else if (envShell.toLowerCase().includes('fish')) {
96
+ return envShell;
97
+ }
98
+ return '/bin/bash';
99
+ }
100
+
55
101
  const PLATFORM_INFO = {
56
102
  platform: os.platform(),
57
103
  platformName: (() => {
@@ -60,7 +106,7 @@ const PLATFORM_INFO = {
60
106
  })(),
61
107
  arch: os.arch(),
62
108
  hostname: os.hostname(),
63
- shell: process.env.SHELL || process.env.COMSPEC || '/bin/sh',
109
+ shell: detectShell(),
64
110
  homeDir: os.homedir(),
65
111
  nodeVersion: process.version
66
112
  };
@@ -106,9 +106,10 @@ enabled: true
106
106
  - **Windows (PowerShell)**:\`New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\\.ai-helper-agent\\skills\\<skill-name>"\`
107
107
  - 如果 \`mkdir\` 报错,尝试不带参数或使用 \`agent_write_file\` 工具在目标路径写入一个临时文件,让系统自动创建父目录。
108
108
 
109
- 5. **写入 SKILL.md**:使用 \`agent_write_file\` 工具将内容写入:
110
- - 路径:\`~/.ai-helper-agent/skills/<skill-name>/SKILL.md\`
111
- - Windows 上路径中的 \`~\` 会自动解析为用户主目录
109
+ 5. **写入 SKILL.md**:使用 \`agent_write_file\` 工具将内容写入。
110
+ - **重要**:\`agent_write_file\` 不会展开 \`~\`,必须使用绝对路径!
111
+ - **macOS/Linux**:从当前工作目录推断用户主目录(工作目录通常是 \`/Users/<你的用户名>/...\`),完整路径为 \`/Users/<你的用户名>/.ai-helper-agent/skills/<skill-name>/SKILL.md\`
112
+ - **Windows**:\`C:\\Users\\<你的用户名>\\.ai-helper-agent\\skills\\<skill-name>\\SKILL.md\`
112
113
 
113
114
  6. **告知用户**:创建完成后,告知用户技能已就绪,说明触发关键词。建议用户在工具箱页面点击「重新加载」使技能生效。
114
115
 
@@ -117,10 +118,10 @@ enabled: true
117
118
  当用户要求更新/完善已有技能时:
118
119
 
119
120
  1. **确认技能名称**:与用户确认要更新的技能名称
120
- 2. **读取现有内容**:使用 \`agent_read_file\` 读取目标 SKILL.md
121
+ 2. **读取现有内容**:使用 \`agent_read_file\` 读取目标 SKILL.md(路径规则同创建流程,需使用绝对路径,如 \`/Users/<你的用户名>/.ai-helper-agent/skills/<skill-name>/SKILL.md\`)
121
122
  3. **分析更新需求**:结合当前对话上下文,识别需要更新的部分
122
123
  4. **合并内容**:保留原技能的核心结构,将新内容融入适当位置
123
- 5. **覆盖写入**:使用 \`agent_write_file\` 覆盖写入 SKILL.md
124
+ 5. **覆盖写入**:使用 \`agent_write_file\` 覆盖写入 SKILL.md(路径规则同上,必须使用绝对路径)
124
125
  6. **告知用户**:告知更新内容,建议重新加载
125
126
 
126
127
  ## 更新注意事项