wattetheria 0.2.8 → 0.2.9
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 +5 -0
- package/lib/cli.js +70 -7
- package/package.json +4 -2
- package/scripts/stage-native-cli.js +84 -0
package/README.md
CHANGED
|
@@ -552,6 +552,11 @@ CLI prerequisites:
|
|
|
552
552
|
|
|
553
553
|
The CLI handles image pull, deployment directory setup, environment generation, container start,
|
|
554
554
|
and health checks internally.
|
|
555
|
+
Agent commands such as `identity`, `wallet`, `servicenet`, and `publish` are forwarded to the
|
|
556
|
+
platform native `wattetheria-client-cli` bundled under `bin/native/<platform>-<arch>/`; installed
|
|
557
|
+
release packages should not require Rust on the user's machine. Release publishing can stage a
|
|
558
|
+
native CLI binary with `npm run stage:native-cli -- --platform <platform> --arch <arch> --source <path>`.
|
|
559
|
+
`WATTETHERIA_CLI_BIN` remains an advanced override for custom local binaries.
|
|
555
560
|
|
|
556
561
|
Version commands:
|
|
557
562
|
|
package/lib/cli.js
CHANGED
|
@@ -29,6 +29,26 @@ const WINDOWS_DOCKER_CANDIDATES = [
|
|
|
29
29
|
"C:\\Program Files\\Docker\\Docker\\resources\\bin\\docker.exe",
|
|
30
30
|
"C:\\Program Files\\Docker\\cli-plugins\\docker.exe"
|
|
31
31
|
];
|
|
32
|
+
const RUST_CLI_BASE_NAME = "wattetheria-client-cli";
|
|
33
|
+
const NATIVE_ARCH_ALIASES = new Map([
|
|
34
|
+
["x64", "x64"],
|
|
35
|
+
["arm64", "arm64"]
|
|
36
|
+
]);
|
|
37
|
+
const BANNER_COMMANDS = new Set([
|
|
38
|
+
"help",
|
|
39
|
+
"install",
|
|
40
|
+
"start",
|
|
41
|
+
"up",
|
|
42
|
+
"update",
|
|
43
|
+
"restart",
|
|
44
|
+
"stop",
|
|
45
|
+
"down",
|
|
46
|
+
"uninstall",
|
|
47
|
+
"doctor"
|
|
48
|
+
]);
|
|
49
|
+
const ANSI_ORANGE = "\x1b[38;5;166m";
|
|
50
|
+
const ANSI_MUTED = "\x1b[38;5;244m";
|
|
51
|
+
const ANSI_RESET = "\x1b[0m";
|
|
32
52
|
|
|
33
53
|
function printHelp() {
|
|
34
54
|
console.log(`Wattetheria CLI ${PACKAGE_JSON.version}
|
|
@@ -52,7 +72,7 @@ Commands:
|
|
|
52
72
|
doctor Check local prerequisites
|
|
53
73
|
help Show this help
|
|
54
74
|
|
|
55
|
-
|
|
75
|
+
Agent subcommands (forwarded to the bundled native CLI when available):
|
|
56
76
|
identity init | show | export-seed
|
|
57
77
|
wallet manage wallet payment accounts
|
|
58
78
|
servicenet provider register
|
|
@@ -485,7 +505,19 @@ function formatCliVersionString() {
|
|
|
485
505
|
}
|
|
486
506
|
|
|
487
507
|
function formatBanner(options) {
|
|
488
|
-
|
|
508
|
+
const wordmark = [
|
|
509
|
+
" __ __ _ _ _ _ _ _ ",
|
|
510
|
+
" \\ \\ / /_ _| |_| |_| |__ ___| |_| |__ ___ _ __(_) __ _ ",
|
|
511
|
+
" \\ \\ /\\ / / _` | __| __| '_ \\ / _ \\ __| '_ \\ / _ \\ '__| |/ _` |",
|
|
512
|
+
" \\ V V / (_| | |_| |_| | | | __/ |_| | | | __/ | | | (_| |",
|
|
513
|
+
" \\_/\\_/ \\__,_|\\__|\\__|_| |_|\\___|\\__|_| |_|\\___|_| |_|\\__,_|"
|
|
514
|
+
].join("\n");
|
|
515
|
+
const subtitle = `${formatReleaseVersionString(options)} - local agent runtime, swarm sync, external agent reach`;
|
|
516
|
+
|
|
517
|
+
if (!supportsBannerColor()) {
|
|
518
|
+
return `${wordmark}\n${subtitle}`;
|
|
519
|
+
}
|
|
520
|
+
return `${ANSI_ORANGE}${wordmark}${ANSI_RESET}\n${ANSI_MUTED}${subtitle}${ANSI_RESET}`;
|
|
489
521
|
}
|
|
490
522
|
|
|
491
523
|
function formatDockerStatusMessage(status) {
|
|
@@ -1170,7 +1202,10 @@ function printImages(options) {
|
|
|
1170
1202
|
}
|
|
1171
1203
|
|
|
1172
1204
|
function shouldPrintBanner(command) {
|
|
1173
|
-
return
|
|
1205
|
+
return isInteractiveTerminal()
|
|
1206
|
+
&& !process.env.CI
|
|
1207
|
+
&& !process.env.WATTETHERIA_NO_BANNER
|
|
1208
|
+
&& BANNER_COMMANDS.has(command);
|
|
1174
1209
|
}
|
|
1175
1210
|
|
|
1176
1211
|
function printBanner(options) {
|
|
@@ -1178,6 +1213,12 @@ function printBanner(options) {
|
|
|
1178
1213
|
console.log("");
|
|
1179
1214
|
}
|
|
1180
1215
|
|
|
1216
|
+
function supportsBannerColor() {
|
|
1217
|
+
return process.stdout.isTTY
|
|
1218
|
+
&& !process.env.NO_COLOR
|
|
1219
|
+
&& process.env.TERM !== "dumb";
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1181
1222
|
// Forwarded subcommands delegate verbatim to the local Rust binary
|
|
1182
1223
|
// `wattetheria-client-cli`. Keep the JS side stupid — no flag parsing here.
|
|
1183
1224
|
const FORWARDED_SUBCOMMANDS = new Set([
|
|
@@ -1187,13 +1228,34 @@ const FORWARDED_SUBCOMMANDS = new Set([
|
|
|
1187
1228
|
"publish",
|
|
1188
1229
|
]);
|
|
1189
1230
|
|
|
1231
|
+
function nativePlatformKey(platform = process.platform, arch = process.arch) {
|
|
1232
|
+
const normalizedArch = NATIVE_ARCH_ALIASES.get(arch);
|
|
1233
|
+
if (!normalizedArch || !["darwin", "linux", "win32"].includes(platform)) {
|
|
1234
|
+
return "";
|
|
1235
|
+
}
|
|
1236
|
+
return `${platform}-${normalizedArch}`;
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
function rustCliBinaryName(platform = process.platform) {
|
|
1240
|
+
return platform === "win32" ? `${RUST_CLI_BASE_NAME}.exe` : RUST_CLI_BASE_NAME;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
function bundledRustBinaryPath() {
|
|
1244
|
+
const platformKey = nativePlatformKey();
|
|
1245
|
+
if (!platformKey) {
|
|
1246
|
+
return "";
|
|
1247
|
+
}
|
|
1248
|
+
return path.join(PACKAGE_ROOT, "bin", "native", platformKey, rustCliBinaryName());
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1190
1251
|
function forwardToRustBinary(commandName, rawArgv) {
|
|
1191
1252
|
// Only the Rust binary name is allowed here. The bare `wattetheria` name
|
|
1192
1253
|
// resolves to this JS shim on most user PATHs (via the npm bin link), so
|
|
1193
1254
|
// including it would create an infinite spawn loop.
|
|
1194
1255
|
const candidates = [
|
|
1195
1256
|
process.env.WATTETHERIA_CLI_BIN,
|
|
1196
|
-
|
|
1257
|
+
bundledRustBinaryPath(),
|
|
1258
|
+
RUST_CLI_BASE_NAME,
|
|
1197
1259
|
].filter(Boolean);
|
|
1198
1260
|
|
|
1199
1261
|
for (const candidate of candidates) {
|
|
@@ -1211,10 +1273,11 @@ function forwardToRustBinary(commandName, rawArgv) {
|
|
|
1211
1273
|
}
|
|
1212
1274
|
}
|
|
1213
1275
|
|
|
1276
|
+
const platformKey = nativePlatformKey() || `${process.platform}-${process.arch}`;
|
|
1214
1277
|
throw new Error(
|
|
1215
|
-
`Could not find the
|
|
1216
|
-
`
|
|
1217
|
-
`
|
|
1278
|
+
`Could not find the Wattetheria native CLI for ${platformKey}. ` +
|
|
1279
|
+
`Install a package that includes bin/native/${platformKey}/${rustCliBinaryName()}, ` +
|
|
1280
|
+
`or set WATTETHERIA_CLI_BIN to the full path of ${rustCliBinaryName()}.`
|
|
1218
1281
|
);
|
|
1219
1282
|
}
|
|
1220
1283
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wattetheria",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Wattetheria deployment CLI",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"bin/",
|
|
10
10
|
"lib/",
|
|
11
|
+
"scripts/stage-native-cli.js",
|
|
11
12
|
".env.release",
|
|
12
13
|
"docker-compose.release.yml",
|
|
13
14
|
"README.md",
|
|
@@ -20,7 +21,8 @@
|
|
|
20
21
|
"access": "public"
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
|
-
"check": "node --check bin/wattetheria.js && node --check lib/cli.js"
|
|
24
|
+
"check": "node --check bin/wattetheria.js && node --check lib/cli.js && node --check scripts/stage-native-cli.js",
|
|
25
|
+
"stage:native-cli": "node scripts/stage-native-cli.js"
|
|
24
26
|
},
|
|
25
27
|
"keywords": [
|
|
26
28
|
"wattetheria",
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const os = require("node:os");
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
|
|
7
|
+
const ROOT_DIR = path.resolve(__dirname, "..");
|
|
8
|
+
const BASE_NAME = "wattetheria-client-cli";
|
|
9
|
+
const SUPPORTED_PLATFORMS = new Set(["darwin", "linux", "win32"]);
|
|
10
|
+
const SUPPORTED_ARCHES = new Set(["x64", "arm64"]);
|
|
11
|
+
|
|
12
|
+
function parseArgs(argv) {
|
|
13
|
+
const options = {
|
|
14
|
+
platform: process.env.WATTETHERIA_NATIVE_PLATFORM || process.platform,
|
|
15
|
+
arch: process.env.WATTETHERIA_NATIVE_ARCH || process.arch,
|
|
16
|
+
source: process.env.WATTETHERIA_NATIVE_CLI_BIN || "",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
20
|
+
const arg = argv[index];
|
|
21
|
+
if (arg === "--platform") {
|
|
22
|
+
options.platform = requireValue(arg, argv[++index]);
|
|
23
|
+
} else if (arg === "--arch") {
|
|
24
|
+
options.arch = requireValue(arg, argv[++index]);
|
|
25
|
+
} else if (arg === "--source") {
|
|
26
|
+
options.source = requireValue(arg, argv[++index]);
|
|
27
|
+
} else {
|
|
28
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return options;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function requireValue(flag, value) {
|
|
36
|
+
if (!value || value.startsWith("-")) {
|
|
37
|
+
throw new Error(`Missing value for ${flag}`);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function binaryName(platform) {
|
|
43
|
+
return platform === "win32" ? `${BASE_NAME}.exe` : BASE_NAME;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function defaultSource(platform) {
|
|
47
|
+
return path.join(ROOT_DIR, "target", "release", binaryName(platform));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function targetKey(platform, arch) {
|
|
51
|
+
if (!SUPPORTED_PLATFORMS.has(platform)) {
|
|
52
|
+
throw new Error(`Unsupported native CLI platform: ${platform}`);
|
|
53
|
+
}
|
|
54
|
+
if (!SUPPORTED_ARCHES.has(arch)) {
|
|
55
|
+
throw new Error(`Unsupported native CLI arch: ${arch}`);
|
|
56
|
+
}
|
|
57
|
+
return `${platform}-${arch}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function stageNativeCli(options) {
|
|
61
|
+
const key = targetKey(options.platform, options.arch);
|
|
62
|
+
const source = path.resolve(options.source || defaultSource(options.platform));
|
|
63
|
+
if (!fs.existsSync(source)) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Native CLI binary not found at ${source}. Build it first or pass --source.`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const targetDir = path.join(ROOT_DIR, "bin", "native", key);
|
|
70
|
+
const target = path.join(targetDir, binaryName(options.platform));
|
|
71
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
72
|
+
fs.copyFileSync(source, target);
|
|
73
|
+
if (options.platform !== "win32") {
|
|
74
|
+
fs.chmodSync(target, 0o755);
|
|
75
|
+
}
|
|
76
|
+
console.log(`staged ${target}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
stageNativeCli(parseArgs(process.argv.slice(2)));
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error(error && error.message ? error.message : String(error));
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|