@keelstackhq/bosun 0.0.0-stage → 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/bin/bosun.js +122 -0
- package/package.json +28 -4
- package/README.md +0 -3
package/bin/bosun.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// npm launcher for bosun: runs the binary from the platform package npm installed through
|
|
5
|
+
// optionalDependencies, with inherited stdio and the binary's exit code. When it cannot start
|
|
6
|
+
// the binary it keeps bosun's contract: one JSON envelope on stdout, the message on stderr.
|
|
7
|
+
|
|
8
|
+
const { spawnSync } = require("node:child_process");
|
|
9
|
+
const fs = require("node:fs");
|
|
10
|
+
const path = require("node:path");
|
|
11
|
+
|
|
12
|
+
/** `process.platform-process.arch` -> platform package (one per release target). */
|
|
13
|
+
const PLATFORMS = {
|
|
14
|
+
"linux-x64": "@keelstackhq/bosun-linux-x64",
|
|
15
|
+
"linux-arm64": "@keelstackhq/bosun-linux-arm64",
|
|
16
|
+
"darwin-x64": "@keelstackhq/bosun-darwin-x64",
|
|
17
|
+
"darwin-arm64": "@keelstackhq/bosun-darwin-arm64",
|
|
18
|
+
"win32-x64": "@keelstackhq/bosun-win32-x64",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function packageFor(platform, arch) {
|
|
22
|
+
return PLATFORMS[`${platform}-${arch}`];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Path of `bin/bosun[.exe]` inside the platform package; throws when it is not installed. */
|
|
26
|
+
function binaryPath(platform, arch, resolve = require.resolve) {
|
|
27
|
+
const pkg = packageFor(platform, arch);
|
|
28
|
+
const dir = path.dirname(resolve(`${pkg}/package.json`));
|
|
29
|
+
return path.join(dir, "bin", platform === "win32" ? "bosun.exe" : "bosun");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Commands with a subcommand; their envelope names both words ("verdict post"). The same list
|
|
34
|
+
* as the `Name(NameCmd)` variants in src/cli/mod.rs; the launcher tests check that.
|
|
35
|
+
*/
|
|
36
|
+
const GROUPS = new Set(["wave", "verdict", "lesson", "hook", "budget"]);
|
|
37
|
+
|
|
38
|
+
/** The envelope's `command` for `args`, as bosun names it; "" when there is none. */
|
|
39
|
+
function commandName(args) {
|
|
40
|
+
const words = [];
|
|
41
|
+
for (let i = 0; i < args.length; i++) {
|
|
42
|
+
const a = args[i];
|
|
43
|
+
if (a === "--") {
|
|
44
|
+
words.push(...args.slice(i + 1));
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
// `-C <DIR>` is bosun's one option that takes a value. A short-flag bundle that ends in C
|
|
48
|
+
// (`-C`, `-vC`) takes the next argument; `-C=DIR` and `-CDIR` carry it.
|
|
49
|
+
if (/^-[a-zA-Z]*C$/.test(a)) i++;
|
|
50
|
+
else if (!a.startsWith("-")) words.push(a);
|
|
51
|
+
}
|
|
52
|
+
if (words.length === 0) return "";
|
|
53
|
+
return GROUPS.has(words[0]) && words.length > 1 ? `${words[0]} ${words[1]}` : words[0];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Report a launcher failure: the message on stderr, one error envelope on stdout; returns 1. */
|
|
57
|
+
function fail(args, message, fix) {
|
|
58
|
+
process.stderr.write(`bosun: ${message}\n`);
|
|
59
|
+
const envelope = {
|
|
60
|
+
version: 1,
|
|
61
|
+
command: commandName(args),
|
|
62
|
+
ok: false,
|
|
63
|
+
exit_code: 1,
|
|
64
|
+
data: {},
|
|
65
|
+
error: { kind: "error", message, fix },
|
|
66
|
+
next: [],
|
|
67
|
+
};
|
|
68
|
+
process.stdout.write(`${JSON.stringify(envelope)}\n`);
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Run bosun with `args`; returns the exit code. */
|
|
73
|
+
function run(args, resolve = require.resolve) {
|
|
74
|
+
const { platform, arch } = process;
|
|
75
|
+
const key = `${platform}-${arch}`;
|
|
76
|
+
const pkg = packageFor(platform, arch);
|
|
77
|
+
if (!pkg) {
|
|
78
|
+
return fail(
|
|
79
|
+
args,
|
|
80
|
+
`no binary for ${key}; supported platforms: ${Object.keys(PLATFORMS).join(", ")}`,
|
|
81
|
+
"use a supported platform, or build from source: cargo install keel-bosun",
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
let bin;
|
|
85
|
+
try {
|
|
86
|
+
bin = binaryPath(platform, arch, resolve);
|
|
87
|
+
} catch {
|
|
88
|
+
return fail(
|
|
89
|
+
args,
|
|
90
|
+
`platform package ${pkg} is not installed`,
|
|
91
|
+
"reinstall @keelstackhq/bosun without --no-optional (or --omit=optional)",
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
let result = spawnSync(bin, args, { stdio: "inherit" });
|
|
95
|
+
if (result.error && result.error.code === "EACCES") {
|
|
96
|
+
// Some installers drop the executable bit; restore it once and retry.
|
|
97
|
+
try {
|
|
98
|
+
fs.chmodSync(bin, 0o755);
|
|
99
|
+
result = spawnSync(bin, args, { stdio: "inherit" });
|
|
100
|
+
} catch {
|
|
101
|
+
// Keep the first error.
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (result.error) {
|
|
105
|
+
return fail(
|
|
106
|
+
args,
|
|
107
|
+
`cannot run ${bin}: ${result.error.message}`,
|
|
108
|
+
"reinstall @keelstackhq/bosun, or build from source: cargo install keel-bosun",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
if (result.signal) {
|
|
112
|
+
process.kill(process.pid, result.signal);
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
return result.status ?? 1;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = { PLATFORMS, GROUPS, packageFor, binaryPath, commandName, run };
|
|
119
|
+
|
|
120
|
+
if (require.main === module) {
|
|
121
|
+
process.exitCode = run(process.argv.slice(2));
|
|
122
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keelstackhq/bosun",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Orchestration helper for repos where agents write all the code (npm launcher for the bosun binary)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/keelstackhq/bosun.git",
|
|
9
|
+
"directory": "npm/bosun"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"bosun": "bin/bosun.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin/"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"optionalDependencies": {
|
|
24
|
+
"@keelstackhq/bosun-linux-x64": "0.1.0",
|
|
25
|
+
"@keelstackhq/bosun-linux-arm64": "0.1.0",
|
|
26
|
+
"@keelstackhq/bosun-darwin-x64": "0.1.0",
|
|
27
|
+
"@keelstackhq/bosun-darwin-arm64": "0.1.0",
|
|
28
|
+
"@keelstackhq/bosun-win32-x64": "0.1.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/README.md
DELETED