@orb44/cli 0.1.7 → 0.1.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.
- package/README.md +4 -4
- package/bin/orb44.mjs +2 -0
- package/package.json +1 -1
- package/server/pulse.mjs +9 -0
- package/server/sat-update.mjs +27 -5
package/README.md
CHANGED
|
@@ -13,11 +13,11 @@ npx @orb44/cli login --url https://orb44.com
|
|
|
13
13
|
Open the printed link in a browser where you are already signed in, confirm the domain, then optionally install the systemd daemon (default no). After a global install the command is `orb44`.
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npx @orb44/cli@0.1.
|
|
17
|
-
npx @orb44/cli@0.1.
|
|
18
|
-
npx @orb44/cli@0.1.
|
|
16
|
+
npx @orb44/cli@0.1.8 status
|
|
17
|
+
npx @orb44/cli@0.1.8 pulse
|
|
18
|
+
npx @orb44/cli@0.1.8 install # later: background pulse, starts after reboot
|
|
19
19
|
orb44 update # after install: replace /usr/lib/orb44-sat from npm
|
|
20
|
-
npx @orb44/cli@0.1.
|
|
20
|
+
npx @orb44/cli@0.1.8 logout
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Do not run bare `npx @orb44/cli` — it can reuse an old cache. Pin the version or use `orb44` after install.
|
package/bin/orb44.mjs
CHANGED
|
@@ -169,6 +169,8 @@ function printAdvice(notes) {
|
|
|
169
169
|
|
|
170
170
|
async function sendPulse(device, { preview = true } = {}) {
|
|
171
171
|
const pulse = collectPulse();
|
|
172
|
+
const ver = readCliVersion(SCRIPT);
|
|
173
|
+
if (ver && ver !== "0.0.0") pulse.cliVersion = ver;
|
|
172
174
|
if (preview) {
|
|
173
175
|
console.log(bold("📡 " + t(lang, "payload")));
|
|
174
176
|
console.log(formatPulsePreview(pulse, lang));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orb44/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Orb44: street snapshot of your site. This CLI is the Watch satellite — pulse from the host (load, listeners, hardening). The cabinet does not run commands on the machine.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/server/pulse.mjs
CHANGED
|
@@ -266,6 +266,7 @@ export function sanitizePulse(raw = {}) {
|
|
|
266
266
|
const limited = Boolean(raw.limited);
|
|
267
267
|
const oom = Boolean(raw.oom) || hardening.oomKills > 0;
|
|
268
268
|
const pressure = sanitizePressure(raw.pressure || raw);
|
|
269
|
+
const cliVersion = sanitizeCliVersion(raw.cliVersion);
|
|
269
270
|
const base = {
|
|
270
271
|
ts: Number(raw.ts) || Date.now(),
|
|
271
272
|
hostname: sanitizeComm(raw.hostname) || os.hostname().slice(0, 40),
|
|
@@ -281,10 +282,18 @@ export function sanitizePulse(raw = {}) {
|
|
|
281
282
|
limited,
|
|
282
283
|
hardening,
|
|
283
284
|
pressure,
|
|
285
|
+
cliVersion,
|
|
284
286
|
};
|
|
285
287
|
return { ...base, gradeInside: gradeInside(base) };
|
|
286
288
|
}
|
|
287
289
|
|
|
290
|
+
function sanitizeCliVersion(raw) {
|
|
291
|
+
const v = String(raw || "").trim();
|
|
292
|
+
if (!/^\d{1,3}\.\d{1,3}\.\d{1,3}(-[a-z0-9.]+)?$/i.test(v)) return null;
|
|
293
|
+
if (v === "0.0.0") return null;
|
|
294
|
+
return v.slice(0, 32);
|
|
295
|
+
}
|
|
296
|
+
|
|
288
297
|
const ADMIN_PORTS = new Set([2019, 2375, 2376, 3306, 5432, 6379, 27017, 9200, 11211, 15672, 8500, 2379, 6443, 9090, 5601, 7474, 7687, 1080, 6432]);
|
|
289
298
|
|
|
290
299
|
const SERVICE_NAME = {
|
package/server/sat-update.mjs
CHANGED
|
@@ -104,13 +104,35 @@ export async function fetchLatestMeta(fetchFn = fetch) {
|
|
|
104
104
|
const version = j?.version;
|
|
105
105
|
const tarball = j?.dist?.tarball;
|
|
106
106
|
if (!version || !tarball) throw new Error("registry meta");
|
|
107
|
-
return { version: String(version), tarball:
|
|
107
|
+
return { version: String(version), tarball: canonicalTarballUrl(tarball) };
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
/** npm metadata uses /@scope/name/; GET of the tarball is more reliable as /@scope%2fname/. */
|
|
111
|
+
export function canonicalTarballUrl(url) {
|
|
112
|
+
try {
|
|
113
|
+
const u = new URL(String(url));
|
|
114
|
+
u.pathname = u.pathname.replace(/^\/@([^/]+)\/([^/]+)\//, "/@$1%2f$2/");
|
|
115
|
+
return u.href;
|
|
116
|
+
} catch {
|
|
117
|
+
return String(url || "");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function unpackTarball(url, tmp, fetchFn = fetch, { retries = 4, delayMs = 1500 } = {}) {
|
|
122
|
+
const href = canonicalTarballUrl(url);
|
|
123
|
+
let last = "fail";
|
|
124
|
+
let buf = null;
|
|
125
|
+
for (let i = 0; i < retries; i++) {
|
|
126
|
+
const r = await fetchFn(href);
|
|
127
|
+
last = r?.status || "fail";
|
|
128
|
+
if (r?.ok) {
|
|
129
|
+
buf = Buffer.from(await r.arrayBuffer());
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
if (Number(last) !== 404 && Number(last) !== 429) break;
|
|
133
|
+
if (i < retries - 1 && delayMs) await new Promise((ok) => setTimeout(ok, delayMs * (i + 1)));
|
|
134
|
+
}
|
|
135
|
+
if (!buf) throw new Error(`tarball ${last}`);
|
|
114
136
|
const tgz = path.join(tmp, "pkg.tgz");
|
|
115
137
|
fs.writeFileSync(tgz, buf);
|
|
116
138
|
const unpack = path.join(tmp, "unpack");
|