@suiflex/kurir 0.0.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/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # @suiflex/kurir
2
+
3
+ Portable MCP server registration for agent harnesses.
4
+
5
+ ```sh
6
+ npm install --global @suiflex/kurir
7
+ kurir clients
8
+ ```
9
+
10
+ The npm package is a thin launcher around the Kurir native binary. It downloads the matching release asset during installation. Use `KURIR_BIN=/path/to/kurir` to run a local build instead.
11
+
12
+ Register a server:
13
+
14
+ ```sh
15
+ kurir register \
16
+ --client opencode \
17
+ --name my-server \
18
+ --command my-server \
19
+ --arg mcp
20
+ ```
21
+
22
+ Check for a newer release or update the native binary:
23
+
24
+ ```sh
25
+ kurir update --check
26
+ kurir update
27
+ ```
28
+
29
+ Use `npm install --global @suiflex/kurir` when you want npm to own the update instead.
30
+
31
+ Set `KURIR_SKIP_INSTALL=1` to skip the postinstall download when a compatible binary is already available through `PATH` or `KURIR_BIN`.
32
+
33
+ Kurir is distributed under the MIT license.
package/bin/kurir.js ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const { spawnSync } = require("node:child_process");
5
+ const fs = require("node:fs");
6
+ const os = require("node:os");
7
+ const path = require("node:path");
8
+
9
+ function candidates() {
10
+ const values = [];
11
+ if (process.env.KURIR_BIN) values.push(process.env.KURIR_BIN);
12
+ const local = path.join(__dirname, "..", "vendor", process.platform, process.arch, "kurir");
13
+ values.push(process.platform === "win32" ? `${local}.exe` : local);
14
+ const lookup = process.platform === "win32" ? "where" : "which";
15
+ const found = spawnSync(lookup, ["kurir"], { encoding: "utf8" });
16
+ if (found.status === 0) {
17
+ for (const entry of found.stdout.split(/\r?\n/).map((value) => value.trim()).filter(Boolean)) {
18
+ if (path.resolve(entry) !== path.resolve(process.argv[1])) values.push(entry);
19
+ }
20
+ }
21
+ return values;
22
+ }
23
+
24
+ function executablePath() {
25
+ for (const candidate of candidates()) {
26
+ try {
27
+ fs.accessSync(candidate, fs.constants.X_OK);
28
+ return candidate;
29
+ } catch {
30
+ // Try the next candidate.
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+
36
+ const binary = executablePath();
37
+ if (!binary) {
38
+ console.error("Kurir binary was not found.");
39
+ console.error("Set KURIR_BIN or install a Kurir release package with its native binary.");
40
+ process.exit(1);
41
+ }
42
+
43
+ const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
44
+ if (result.error) {
45
+ console.error(`Could not start Kurir: ${result.error.message}`);
46
+ process.exit(1);
47
+ }
48
+ process.exit(result.status ?? 1);
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@suiflex/kurir",
3
+ "version": "0.0.0",
4
+ "description": "Portable MCP server registration and harness integration toolkit",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/suiflex/kurir.git",
9
+ "directory": "npm"
10
+ },
11
+ "homepage": "https://github.com/suiflex/kurir",
12
+ "bugs": {
13
+ "url": "https://github.com/suiflex/kurir/issues"
14
+ },
15
+ "keywords": ["mcp", "model-context-protocol", "harness", "registration", "cli"],
16
+ "bin": {
17
+ "kurir": "bin/kurir.js"
18
+ },
19
+ "files": [
20
+ "README.md",
21
+ "bin/",
22
+ "scripts/"
23
+ ],
24
+ "engines": {
25
+ "node": ">=18"
26
+ },
27
+ "scripts": {
28
+ "postinstall": "node scripts/install.js",
29
+ "test": "node --test test/*.test.js"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ }
34
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ const { execFileSync } = require("node:child_process");
4
+ const fs = require("node:fs");
5
+ const os = require("node:os");
6
+ const path = require("node:path");
7
+
8
+ const packageRoot = path.resolve(__dirname, "..");
9
+ const version = process.env.npm_package_version || require(path.join(packageRoot, "package.json")).version;
10
+ const vendorRoot = path.join(packageRoot, "vendor", process.platform, process.arch);
11
+ const binaryName = process.platform === "win32" ? "kurir.exe" : "kurir";
12
+ const binaryPath = path.join(vendorRoot, binaryName);
13
+
14
+ if (process.env.KURIR_SKIP_INSTALL === "1" || process.env.KURIR_BIN) process.exit(0);
15
+ if (fs.existsSync(binaryPath)) process.exit(0);
16
+
17
+ const target = targetName();
18
+ const base = `https://github.com/suiflex/kurir/releases/download/v${version}`;
19
+ const temp = fs.mkdtempSync(path.join(os.tmpdir(), "kurir-install-"));
20
+ const archive = path.join(temp, process.platform === "win32" ? "kurir.zip" : "kurir.tar.gz");
21
+ try {
22
+ download(`${base}/kurir-${version}-${target}.${process.platform === "win32" ? "zip" : "tar.gz"}`, archive);
23
+ fs.mkdirSync(vendorRoot, { recursive: true });
24
+ if (process.platform === "win32") {
25
+ execFileSync("powershell", ["-NoProfile", "-Command", `Expand-Archive -Force '${archive}' '${temp}/expanded'`], { stdio: "inherit" });
26
+ fs.copyFileSync(path.join(temp, "expanded", "kurir.exe"), binaryPath);
27
+ } else {
28
+ execFileSync("tar", ["-xzf", archive, "-C", temp], { stdio: "inherit" });
29
+ fs.copyFileSync(path.join(temp, "kurir"), binaryPath);
30
+ fs.chmodSync(binaryPath, 0o755);
31
+ }
32
+ } catch (error) {
33
+ console.error(`Kurir binary installation failed: ${error.message}`);
34
+ console.error("Set KURIR_BIN to a compatible binary or KURIR_SKIP_INSTALL=1 to skip the download.");
35
+ process.exit(1);
36
+ } finally {
37
+ fs.rmSync(temp, { recursive: true, force: true });
38
+ }
39
+
40
+ function targetName() {
41
+ const arch = process.arch === "arm64" ? "aarch64" : process.arch === "x64" ? "x86_64" : process.arch;
42
+ const platform = process.platform === "darwin" ? "darwin" : process.platform === "win32" ? "windows" : process.platform;
43
+ if (!['darwin', 'linux', 'windows'].includes(platform) || !['aarch64', 'x86_64'].includes(arch)) {
44
+ throw new Error(`unsupported platform ${process.platform}-${process.arch}`);
45
+ }
46
+ return `${platform}-${arch}`;
47
+ }
48
+
49
+ function download(url, destination) {
50
+ const script = [
51
+ "const fs = require('node:fs');",
52
+ "const [url, destination] = process.argv.slice(1);",
53
+ "fetch(url).then(async (response) => {",
54
+ " if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);",
55
+ " fs.writeFileSync(destination, Buffer.from(await response.arrayBuffer()));",
56
+ "}).catch((error) => { console.error(error.message); process.exit(1); });",
57
+ ].join(" ");
58
+ execFileSync(process.execPath, ["-e", script, url, destination], { stdio: "inherit" });
59
+ }