@twinsearth/im2agent 0.0.0-stage → 1.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +20 -2
  2. package/bin/im2a.js +81 -0
  3. package/package.json +30 -3
package/README.md CHANGED
@@ -1,3 +1,21 @@
1
- # Temporary Holding Version
1
+ # im2agent (npm CLI)
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ IM2A gateway 的跨平台 npm 启动器。安装后可用 `im2a` 命令启动网关,
4
+ 首次运行会从 GitHub Release 下载对应平台的 Go 二进制并缓存到 `~/.im2a/bin/<version>`。
5
+
6
+ ```bash
7
+ npm install -g @twinsearth/im2agent
8
+ im2a -port 8080
9
+ curl http://127.0.0.1:8080/healthz
10
+ ```
11
+
12
+ ## 开发 / 离线测试
13
+
14
+ 用本地已编译的二进制(跳过下载):
15
+
16
+ ```bash
17
+ export IM2A_BIN=/path/to/im2a-gateway_linux_amd64
18
+ im2a -port 8080
19
+ ```
20
+
21
+ 平台覆盖:linux / darwin / windows × amd64 / arm64。版本与 Go 后端同步(当前 1.8.8)。
package/bin/im2a.js ADDED
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // im2a: IM2A gateway 跨平台启动器。
4
+ // 优先级:IM2A_BIN 环境变量(开发/测试)> 本地缓存 > 从 GitHub Release 下载。
5
+ const os = require('os');
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const https = require('https');
9
+ const { spawn } = require('child_process');
10
+ const { execFileSync } = require('child_process');
11
+
12
+ const PKG_VERSION = '1.8.8';
13
+ const REPO = 'TwinsEarth/im2agent';
14
+
15
+ function platformAsset() {
16
+ const goos = process.platform === 'darwin' ? 'darwin'
17
+ : process.platform === 'win32' ? 'windows' : 'linux';
18
+ const goarch = process.arch === 'arm64' ? 'arm64'
19
+ : process.arch === 'x64' ? 'amd64' : null;
20
+ if (!goarch) throw new Error('unsupported arch: ' + process.arch);
21
+ const ext = goos === 'windows' ? '.exe' : '';
22
+ return `im2a-gateway_${goos}_${goarch}${ext}`;
23
+ }
24
+
25
+ function cacheDir() {
26
+ const d = path.join(os.homedir(), '.im2a', 'bin', PKG_VERSION);
27
+ fs.mkdirSync(d, { recursive: true });
28
+ return d;
29
+ }
30
+
31
+ function download(url, dest) {
32
+ return new Promise((resolve, reject) => {
33
+ const follow = (u) => https.get(u, (res) => {
34
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
35
+ return follow(res.headers.location);
36
+ }
37
+ if (res.statusCode !== 200) {
38
+ return reject(new Error('download failed HTTP ' + res.statusCode + ' ' + u));
39
+ }
40
+ const tmp = dest + '.part';
41
+ const out = fs.createWriteStream(tmp);
42
+ res.pipe(out);
43
+ out.on('finish', () => { out.close(() => { fs.renameSync(tmp, dest); resolve(); }); });
44
+ out.on('error', reject);
45
+ }).on('error', reject);
46
+ follow(url);
47
+ });
48
+ }
49
+
50
+ async function resolveBinary() {
51
+ const asset = platformAsset();
52
+ if (process.env.IM2A_BIN) {
53
+ if (!fs.existsSync(process.env.IM2A_BIN)) throw new Error('IM2A_BIN not found: ' + process.env.IM2A_BIN);
54
+ return process.env.IM2A_BIN;
55
+ }
56
+ const cached = path.join(cacheDir(), asset);
57
+ if (fs.existsSync(cached)) return cached;
58
+ const url = `https://github.com/${REPO}/releases/download/v${PKG_VERSION}/${asset}`;
59
+ process.stderr.write(`[im2a] downloading ${asset} from ${url}\n`);
60
+ await download(url, cached);
61
+ if (process.platform !== 'win32') fs.chmodSync(cached, 0o755);
62
+ return cached;
63
+ }
64
+
65
+ (async () => {
66
+ try {
67
+ const args = process.argv.slice(2);
68
+ // --im2a-version 只打印启动器与二进制版本(自检/冒烟,不下载)
69
+ if (args.includes('--im2a-version')) {
70
+ process.stdout.write(`im2a launcher v${PKG_VERSION} (asset ${platformAsset()})\n`);
71
+ return;
72
+ }
73
+ const bin = await resolveBinary();
74
+ const child = spawn(bin, args, { stdio: 'inherit' });
75
+ child.on('exit', (code) => process.exit(code || 0));
76
+ child.on('error', (e) => { process.stderr.write(String(e.message || e) + '\n'); process.exit(1); });
77
+ } catch (e) {
78
+ process.stderr.write('[im2a] ' + (e.message || e) + '\n');
79
+ process.exit(1);
80
+ }
81
+ })();
package/package.json CHANGED
@@ -1,6 +1,33 @@
1
1
  {
2
2
  "name": "@twinsearth/im2agent",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.8.8",
4
+ "description": "IM2A gateway CLI launcher — human-agent hybrid IM (connect Agent networks, human keeps final approval).",
5
+ "bin": {
6
+ "im2a": "bin/im2a.js"
7
+ },
8
+ "files": [
9
+ "bin",
10
+ "README.md"
11
+ ],
12
+ "engines": {
13
+ "node": ">=18"
14
+ },
15
+ "keywords": [
16
+ "im2a",
17
+ "agent",
18
+ "im",
19
+ "human-agent",
20
+ "gateway",
21
+ "approval",
22
+ "ai-secretary"
23
+ ],
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/TwinsEarth/im2agent.git"
28
+ },
29
+ "homepage": "https://github.com/TwinsEarth/im2agent#readme",
30
+ "bugs": {
31
+ "url": "https://github.com/TwinsEarth/im2agent/issues"
32
+ }
6
33
  }