imtoagent 0.3.11 → 0.3.13

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.
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { execSync } from 'child_process';
6
6
  import * as fs from 'fs';
7
+ import * as os from 'os';
7
8
  import * as path from 'path';
8
9
 
9
10
  export interface BackendInfo {
@@ -60,10 +61,10 @@ function checkOne(b: Omit<BackendInfo, 'installed' | 'version'>): BackendInfo {
60
61
  const version = execSync(versionCmd[b.type], { encoding: 'utf-8', timeout: 5000 }).trim();
61
62
  return { ...b, installed: true, version };
62
63
  } catch {
63
- // PATH 中找不到,继续尝试 npm global bin
64
+ // PATH 中找不到,继续尝试 fallback
64
65
  }
65
66
 
66
- // fallback:直接从 npm global bin 目录运行
67
+ // fallback 1: npm global bin
67
68
  const npmBin = getNpmGlobalBin();
68
69
  if (npmBin) {
69
70
  const binPath = path.join(npmBin, b.type);
@@ -77,6 +78,17 @@ function checkOne(b: Omit<BackendInfo, 'installed' | 'version'>): BackendInfo {
77
78
  }
78
79
  }
79
80
 
81
+ // fallback 2: OpenCode custom install path
82
+ if (b.type === 'opencode') {
83
+ const opencodePath = path.join(os.homedir(), '.opencode', 'bin', 'opencode');
84
+ try {
85
+ if (fs.existsSync(opencodePath)) {
86
+ const version = execSync(`"${opencodePath}" version`, { encoding: 'utf-8', timeout: 5000 }).trim();
87
+ return { ...b, installed: true, version };
88
+ }
89
+ } catch {}
90
+ }
91
+
80
92
  return { ...b, installed: false, version: null };
81
93
  }
82
94
 
@@ -99,6 +111,38 @@ export function formatBackendStatus(backends: BackendInfo[]): string {
99
111
  }).join('\n');
100
112
  }
101
113
 
114
+ // ================================================================
115
+ // Shell config helpers — auto-add paths for user
116
+ // ================================================================
117
+
118
+ function getShellConfigFile(): string | null {
119
+ const candidates = ['.zshrc', '.bashrc', '.bash_profile', '.profile'];
120
+ const home = os.homedir();
121
+ for (const name of candidates) {
122
+ const p = path.join(home, name);
123
+ if (fs.existsSync(p)) return p;
124
+ }
125
+ // fallback: create .zshrc on macOS
126
+ if (process.platform === 'darwin') {
127
+ return path.join(home, '.zshrc');
128
+ }
129
+ return null;
130
+ }
131
+
132
+ function ensurePathInConfig(configPath: string, binDir: string): void {
133
+ const exportLine = `export PATH="${binDir}:$PATH"`;
134
+ try {
135
+ if (fs.existsSync(configPath)) {
136
+ const content = fs.readFileSync(configPath, 'utf-8');
137
+ // Skip if already present
138
+ if (content.includes(binDir)) return;
139
+ }
140
+ fs.appendFileSync(configPath, `\n# Added by imtoagent setup\n${exportLine}\n`);
141
+ // Also update current process.env for immediate detection
142
+ process.env.PATH = `${binDir}:${process.env.PATH}`;
143
+ } catch {}
144
+ }
145
+
102
146
  // ================================================================
103
147
  // 自动安装后端 CLI
104
148
  // ================================================================
@@ -159,7 +203,8 @@ export async function installBackend(
159
203
  return false;
160
204
  }
161
205
 
162
- // 安装完成后验证 — 优先用 npm bin 目录直接检查
206
+ // 安装完成后验证 — 按优先级依次检查
207
+ // 1) npm global bin
163
208
  if (npmBinDir) {
164
209
  const binPath = path.join(npmBinDir, b.type);
165
210
  try {
@@ -171,7 +216,25 @@ export async function installBackend(
171
216
  } catch {}
172
217
  }
173
218
 
174
- // fallback: 通过 PATH 查找
219
+ // 2) OpenCode custom install path
220
+ if (type === 'opencode') {
221
+ const opencodeBinDir = path.join(os.homedir(), '.opencode', 'bin');
222
+ const opencodePath = path.join(opencodeBinDir, 'opencode');
223
+ if (fs.existsSync(opencodePath)) {
224
+ try {
225
+ const version = execSync(`"${opencodePath}" version`, { encoding: 'utf-8', timeout: 5000 }).trim();
226
+ // 自动配置 PATH(如果 shell 配置文件存在且未包含该行)
227
+ const shellConfig = getShellConfigFile();
228
+ if (shellConfig) {
229
+ ensurePathInConfig(shellConfig, opencodeBinDir);
230
+ }
231
+ console.log(`\n✅ ${b.label} installed successfully! Version: ${version}`);
232
+ return true;
233
+ } catch {}
234
+ }
235
+ }
236
+
237
+ // 3) via PATH
175
238
  const info = checkOne(b);
176
239
  if (info.installed) {
177
240
  console.log(`\n✅ ${b.label} installed successfully! Version: ${info.version}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imtoagent",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "description": "IM ↔ Agent 统一网关 — 飞书/Telegram/微信/企业微信对接 Claude Code/Codex/OpenCode",
5
5
  "type": "module",
6
6
  "bin": {