@binoctal/open-agents-bridge 0.1.0
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/install.js +185 -0
- package/package.json +37 -0
- package/run.js +17 -0
package/install.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
const https = require("https");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const { execSync } = require("child_process");
|
|
6
|
+
|
|
7
|
+
const REPO_OWNER = "binoctal";
|
|
8
|
+
const REPO_NAME = "open-agents-bridge";
|
|
9
|
+
const BINARY_NAME = "open-agents";
|
|
10
|
+
|
|
11
|
+
function getPlatform() {
|
|
12
|
+
const platform = os.platform();
|
|
13
|
+
const arch = os.arch();
|
|
14
|
+
|
|
15
|
+
const osMap = {
|
|
16
|
+
darwin: "darwin",
|
|
17
|
+
linux: "linux",
|
|
18
|
+
win32: "windows",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const archMap = {
|
|
22
|
+
x64: "amd64",
|
|
23
|
+
arm64: "arm64",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const goos = osMap[platform];
|
|
27
|
+
const goarch = archMap[arch];
|
|
28
|
+
|
|
29
|
+
if (!goos || !goarch) {
|
|
30
|
+
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return { goos, goarch, ext: platform === "win32" ? ".exe" : "" };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function fetchJSON(url) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
https
|
|
39
|
+
.get(
|
|
40
|
+
url,
|
|
41
|
+
{ headers: { "User-Agent": "open-agents-bridge-npm" } },
|
|
42
|
+
(res) => {
|
|
43
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
44
|
+
return fetchJSON(res.headers.location).then(resolve, reject);
|
|
45
|
+
}
|
|
46
|
+
if (res.statusCode !== 200) {
|
|
47
|
+
return reject(new Error(`HTTP ${res.statusCode} from ${url}`));
|
|
48
|
+
}
|
|
49
|
+
let data = "";
|
|
50
|
+
res.on("data", (chunk) => (data += chunk));
|
|
51
|
+
res.on("end", () => {
|
|
52
|
+
try {
|
|
53
|
+
resolve(JSON.parse(data));
|
|
54
|
+
} catch (e) {
|
|
55
|
+
reject(e);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
.on("error", reject);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function downloadFile(url, destPath) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const file = fs.createWriteStream(destPath);
|
|
67
|
+
https
|
|
68
|
+
.get(url, (res) => {
|
|
69
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
70
|
+
file.close();
|
|
71
|
+
fs.unlinkSync(destPath);
|
|
72
|
+
return downloadFile(res.headers.location, destPath).then(resolve, reject);
|
|
73
|
+
}
|
|
74
|
+
if (res.statusCode !== 200) {
|
|
75
|
+
file.close();
|
|
76
|
+
fs.unlinkSync(destPath);
|
|
77
|
+
return reject(new Error(`HTTP ${res.statusCode} downloading ${url}`));
|
|
78
|
+
}
|
|
79
|
+
res.pipe(file);
|
|
80
|
+
file.on("finish", () => {
|
|
81
|
+
file.close(resolve);
|
|
82
|
+
});
|
|
83
|
+
})
|
|
84
|
+
.on("error", (err) => {
|
|
85
|
+
file.close();
|
|
86
|
+
fs.unlinkSync(destPath);
|
|
87
|
+
reject(err);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function install() {
|
|
93
|
+
const { goos, goarch, ext } = getPlatform();
|
|
94
|
+
|
|
95
|
+
console.log(`Detecting platform: ${goos}/${goarch}`);
|
|
96
|
+
|
|
97
|
+
// Get latest release from GitHub
|
|
98
|
+
const apiUrl = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases/latest`;
|
|
99
|
+
console.log("Fetching latest release...");
|
|
100
|
+
|
|
101
|
+
let release;
|
|
102
|
+
try {
|
|
103
|
+
release = await fetchJSON(apiUrl);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error(
|
|
106
|
+
"Failed to fetch release info. If you are installing from source, build the binary manually."
|
|
107
|
+
);
|
|
108
|
+
console.error(` Error: ${err.message}`);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Find matching asset
|
|
113
|
+
const suffix = `${goos}_${goarch}`;
|
|
114
|
+
const asset = release.assets.find((a) => a.name.includes(suffix));
|
|
115
|
+
|
|
116
|
+
if (!asset) {
|
|
117
|
+
console.error(`No binary found for ${suffix} in release ${release.tag_name}`);
|
|
118
|
+
console.error(
|
|
119
|
+
"Available assets:",
|
|
120
|
+
release.assets.map((a) => a.name).join(", ")
|
|
121
|
+
);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Download and extract
|
|
126
|
+
const binDir = path.join(__dirname, "bin");
|
|
127
|
+
if (!fs.existsSync(binDir)) {
|
|
128
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const binaryName = BINARY_NAME + ext;
|
|
132
|
+
const binaryPath = path.join(binDir, binaryName);
|
|
133
|
+
|
|
134
|
+
console.log(`Downloading ${asset.name}...`);
|
|
135
|
+
|
|
136
|
+
if (asset.name.endsWith(".tar.gz")) {
|
|
137
|
+
const tmpArchive = path.join(binDir, asset.name);
|
|
138
|
+
await downloadFile(asset.browser_download_url, tmpArchive);
|
|
139
|
+
|
|
140
|
+
// Extract the binary from tarball
|
|
141
|
+
try {
|
|
142
|
+
if (goos === "darwin" || goos === "linux") {
|
|
143
|
+
execSync(`tar -xzf "${tmpArchive}" -C "${binDir}" "${binaryName}"`, {
|
|
144
|
+
stdio: "pipe",
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
} catch (e) {
|
|
148
|
+
// Fallback: try extracting the entire archive
|
|
149
|
+
execSync(`tar -xzf "${tmpArchive}" -C "${binDir}"`, { stdio: "pipe" });
|
|
150
|
+
}
|
|
151
|
+
fs.unlinkSync(tmpArchive);
|
|
152
|
+
} else if (asset.name.endsWith(".zip")) {
|
|
153
|
+
const tmpArchive = path.join(binDir, asset.name);
|
|
154
|
+
await downloadFile(asset.browser_download_url, tmpArchive);
|
|
155
|
+
|
|
156
|
+
// Extract using built-in or system unzip
|
|
157
|
+
try {
|
|
158
|
+
execSync(`unzip -o "${tmpArchive}" "${binaryName}" -d "${binDir}"`, {
|
|
159
|
+
stdio: "pipe",
|
|
160
|
+
});
|
|
161
|
+
} catch (e) {
|
|
162
|
+
// Fallback: try powershell on Windows
|
|
163
|
+
execSync(
|
|
164
|
+
`powershell -command "Expand-Archive -Path '${tmpArchive}' -DestinationPath '${binDir}' -Force"`,
|
|
165
|
+
{ stdio: "pipe" }
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
fs.unlinkSync(tmpArchive);
|
|
169
|
+
} else {
|
|
170
|
+
// Plain binary
|
|
171
|
+
await downloadFile(asset.browser_download_url, binaryPath);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Make executable (unix)
|
|
175
|
+
if (goos !== "windows") {
|
|
176
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.log(`Successfully installed open-agents ${release.tag_name}`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
install().catch((err) => {
|
|
183
|
+
console.error("Installation failed:", err.message);
|
|
184
|
+
process.exit(1);
|
|
185
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@binoctal/open-agents-bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Bridge CLI for Open Agents - connect your devices to the agent network",
|
|
5
|
+
"bin": {
|
|
6
|
+
"open-agents": "./run.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node install.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"install.js",
|
|
13
|
+
"run.js"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"open-agents",
|
|
20
|
+
"bridge",
|
|
21
|
+
"cli",
|
|
22
|
+
"agents",
|
|
23
|
+
"remote-control"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=16"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/binoctal/open-agents-bridge.git"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/binoctal/open-agents-bridge/issues"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/binoctal/open-agents-bridge#readme"
|
|
37
|
+
}
|
package/run.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
|
|
7
|
+
const ext = os.platform() === "win32" ? ".exe" : "";
|
|
8
|
+
const binaryPath = path.join(__dirname, "bin", `open-agents${ext}`);
|
|
9
|
+
|
|
10
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
11
|
+
stdio: "inherit",
|
|
12
|
+
env: process.env,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
child.on("exit", (code) => {
|
|
16
|
+
process.exit(code ?? 1);
|
|
17
|
+
});
|