@legioncodeinc/hive 0.5.0 → 0.6.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 +2 -0
- package/dist/cli-commands.d.ts +20 -0
- package/dist/cli-commands.js +93 -2
- package/dist/cli-commands.js.map +1 -1
- package/dist/cli.js +8 -2
- package/dist/cli.js.map +1 -1
- package/dist/daemon/dashboard/app.js +9 -9
- package/dist/daemon/installer/manifest-snapshot.json +5 -5
- package/dist/dashboard/web/onboarding/login-step.js +25 -13
- package/dist/dashboard/web/onboarding/login-step.js.map +1 -1
- package/dist/dashboard/web/setup-gate.js +11 -1
- package/dist/dashboard/web/setup-gate.js.map +1 -1
- package/dist/dashboard/web/wire.d.ts +2 -2
- package/dist/install/registry.d.ts +6 -0
- package/dist/install/registry.js +68 -1
- package/dist/install/registry.js.map +1 -1
- package/dist/install/state-dir.d.ts +11 -0
- package/dist/install/state-dir.js +40 -0
- package/dist/install/state-dir.js.map +1 -0
- package/dist/service/commands.d.ts +1 -0
- package/dist/service/commands.js +10 -0
- package/dist/service/commands.js.map +1 -1
- package/dist/service/index.d.ts +25 -1
- package/dist/service/index.js +146 -6
- package/dist/service/index.js.map +1 -1
- package/dist/shared/fleet-readiness.js +13 -2
- package/dist/shared/fleet-readiness.js.map +1 -1
- package/package.json +1 -1
package/dist/service/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
|
-
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { resolveStagedWindowsTaskPath } from "../shared/apiary-root.js";
|
|
5
5
|
import { migrateHiveState } from "../shared/state-migration.js";
|
|
6
|
-
import { installCommands, legacyUninstallCommands, uninstallCommands } from "./commands.js";
|
|
7
|
-
import { legacyUnitPath, resolveServiceContext, resolveServicePlan } from "./platform.js";
|
|
6
|
+
import { installCommands, legacyUninstallCommands, stopCommands, uninstallCommands } from "./commands.js";
|
|
7
|
+
import { legacyUnitPath, LEGACY_WINDOWS_TASK_NAME, resolveServiceContext, resolveServicePlan, WINDOWS_TASK_NAME } from "./platform.js";
|
|
8
8
|
import { renderUnit } from "./templates.js";
|
|
9
9
|
const SERVICE_COMMAND_TIMEOUT_MS = 15_000;
|
|
10
10
|
export function createExecFileRunner() {
|
|
@@ -40,6 +40,9 @@ export function createNodeServiceFs() {
|
|
|
40
40
|
},
|
|
41
41
|
removeFile(path) {
|
|
42
42
|
rmSync(path, { force: true });
|
|
43
|
+
},
|
|
44
|
+
fileExists(path) {
|
|
45
|
+
return existsSync(path);
|
|
43
46
|
}
|
|
44
47
|
};
|
|
45
48
|
}
|
|
@@ -67,13 +70,69 @@ function scopePhrase(plan) {
|
|
|
67
70
|
}
|
|
68
71
|
async function runAll(runner, commands) {
|
|
69
72
|
let firstFailure = null;
|
|
73
|
+
let firstFailureResult = null;
|
|
70
74
|
for (const command of commands) {
|
|
71
75
|
const result = await runner.run(command.command, command.args, { timeoutMs: SERVICE_COMMAND_TIMEOUT_MS });
|
|
72
76
|
if (!result.ok && firstFailure === null) {
|
|
73
77
|
firstFailure = command;
|
|
78
|
+
firstFailureResult = result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return { allOk: firstFailure === null, firstFailure, firstFailureResult };
|
|
82
|
+
}
|
|
83
|
+
/** Cap how much of a command's own output is ever echoed back in a result message. */
|
|
84
|
+
const MAX_FAILURE_DETAIL_CHARS = 200;
|
|
85
|
+
function lastNonEmptyLine(text) {
|
|
86
|
+
const lines = text
|
|
87
|
+
.split(/\r?\n/)
|
|
88
|
+
.map((line) => line.trim())
|
|
89
|
+
.filter((line) => line !== "");
|
|
90
|
+
return lines.length > 0 ? (lines[lines.length - 1] ?? null) : null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Reduce a failed {@link CommandResult} to one short, secret-free line worth
|
|
94
|
+
* surfacing to the operator (e.g. "No such process", "Access is denied.").
|
|
95
|
+
* Prefers the runner's own `detail` (a spawn-error message); otherwise falls
|
|
96
|
+
* back to the last non-empty line of stderr, then stdout, since launchctl/
|
|
97
|
+
* systemctl/schtasks all print their real error there. A genuine failure must
|
|
98
|
+
* surface the underlying error rather than a generic "something failed" -
|
|
99
|
+
* that is what lets an operator tell a real problem from a no-op.
|
|
100
|
+
*/
|
|
101
|
+
function describeFailure(result) {
|
|
102
|
+
if (result === null)
|
|
103
|
+
return "unknown error";
|
|
104
|
+
const candidate = result.detail ?? lastNonEmptyLine(result.stderr) ?? lastNonEmptyLine(result.stdout) ?? "unknown error";
|
|
105
|
+
return candidate.length > MAX_FAILURE_DETAIL_CHARS
|
|
106
|
+
? `${candidate.slice(0, MAX_FAILURE_DETAIL_CHARS)}...`
|
|
107
|
+
: candidate;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* True when a failed stop/uninstall command's result indicates the unit was
|
|
111
|
+
* already absent (not currently registered/running) rather than a genuine
|
|
112
|
+
* failure. Each service manager reports "not found" differently; launchd's
|
|
113
|
+
* `ESRCH`-derived exit code (3) is locale-independent so it is checked
|
|
114
|
+
* directly. Every manager additionally falls back to a broad, case-insensitive
|
|
115
|
+
* text match over stdout/stderr/detail. Anything that does not match is
|
|
116
|
+
* conservatively treated as a GENUINE failure (never silently swallowed) -
|
|
117
|
+
* this is the classification M-2 / AC-9 / b-AC-6 depend on.
|
|
118
|
+
*/
|
|
119
|
+
function isAlreadyAbsentFailure(manager, result) {
|
|
120
|
+
if (result === null)
|
|
121
|
+
return false;
|
|
122
|
+
const text = `${result.detail ?? ""} ${result.stderr} ${result.stdout}`.toLowerCase();
|
|
123
|
+
const genericAbsent = /does not exist|cannot find|no such process|not[- ]loaded|could not find|not found/;
|
|
124
|
+
switch (manager) {
|
|
125
|
+
case "launchd":
|
|
126
|
+
return result.code === 3 || genericAbsent.test(text);
|
|
127
|
+
case "systemd":
|
|
128
|
+
return genericAbsent.test(text);
|
|
129
|
+
case "schtasks":
|
|
130
|
+
return genericAbsent.test(text);
|
|
131
|
+
default: {
|
|
132
|
+
const unreachable = manager;
|
|
133
|
+
return unreachable;
|
|
74
134
|
}
|
|
75
135
|
}
|
|
76
|
-
return { allOk: firstFailure === null, firstFailure };
|
|
77
136
|
}
|
|
78
137
|
function withResolvedUnitPath(plan) {
|
|
79
138
|
if (plan.manager !== "schtasks" || plan.unitPath !== "")
|
|
@@ -95,7 +154,32 @@ export function createServiceModule(deps) {
|
|
|
95
154
|
function plan() {
|
|
96
155
|
return resolveServicePlan(environment);
|
|
97
156
|
}
|
|
157
|
+
async function isRegisteredForPlan(resolvedPlan) {
|
|
158
|
+
if (resolvedPlan.manager === "schtasks") {
|
|
159
|
+
const current = await runner.run("schtasks", ["/Query", "/TN", WINDOWS_TASK_NAME], {
|
|
160
|
+
timeoutMs: SERVICE_COMMAND_TIMEOUT_MS
|
|
161
|
+
});
|
|
162
|
+
if (current.ok)
|
|
163
|
+
return true;
|
|
164
|
+
const legacy = await runner.run("schtasks", ["/Query", "/TN", LEGACY_WINDOWS_TASK_NAME], {
|
|
165
|
+
timeoutMs: SERVICE_COMMAND_TIMEOUT_MS
|
|
166
|
+
});
|
|
167
|
+
return legacy.ok;
|
|
168
|
+
}
|
|
169
|
+
if (resolvedPlan.unitPath !== "" && fs.fileExists(resolvedPlan.unitPath))
|
|
170
|
+
return true;
|
|
171
|
+
const legacyPath = legacyUnitPath(resolvedPlan);
|
|
172
|
+
return legacyPath !== "" && fs.fileExists(legacyPath);
|
|
173
|
+
}
|
|
98
174
|
return {
|
|
175
|
+
async isRegistered() {
|
|
176
|
+
try {
|
|
177
|
+
return await isRegisteredForPlan(withResolvedUnitPath(plan()));
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
},
|
|
99
183
|
async install() {
|
|
100
184
|
let resolvedPlan;
|
|
101
185
|
try {
|
|
@@ -146,6 +230,39 @@ export function createServiceModule(deps) {
|
|
|
146
230
|
message: `hive registered as a ${scopePhrase(resolvedPlan)} service and started. It will restart on crash and start on boot/login.`
|
|
147
231
|
};
|
|
148
232
|
},
|
|
233
|
+
async stop() {
|
|
234
|
+
let resolvedPlan;
|
|
235
|
+
try {
|
|
236
|
+
resolvedPlan = withResolvedUnitPath(plan());
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
return {
|
|
240
|
+
ok: false,
|
|
241
|
+
message: `Could not stop hive service: ${error instanceof Error ? error.message : "unknown error"}.`
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
const { allOk, firstFailure, firstFailureResult } = await runAll(runner, stopCommands(resolvedPlan, uid));
|
|
245
|
+
if (!allOk) {
|
|
246
|
+
// M-2 posture applied to stop too: a manager reporting "already not running/
|
|
247
|
+
// loaded" (e.g. a repeat `hive stop`, or launchd having nothing left to boot
|
|
248
|
+
// out) is a friendly no-op, not a failure - there is nothing left to stop
|
|
249
|
+
// either way. A genuine failure still fails honestly with the real detail.
|
|
250
|
+
if (isAlreadyAbsentFailure(resolvedPlan.manager, firstFailureResult)) {
|
|
251
|
+
return {
|
|
252
|
+
ok: true,
|
|
253
|
+
message: `hive service was already stopped (${scopePhrase(resolvedPlan)}).`
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
ok: false,
|
|
258
|
+
message: `A service-manager stop command (${firstFailure?.command ?? "unknown"}) reported an error: ${describeFailure(firstFailureResult)}.`
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
ok: true,
|
|
263
|
+
message: `hive service stopped (${scopePhrase(resolvedPlan)}).`
|
|
264
|
+
};
|
|
265
|
+
},
|
|
149
266
|
async uninstall() {
|
|
150
267
|
let resolvedPlan;
|
|
151
268
|
try {
|
|
@@ -154,25 +271,48 @@ export function createServiceModule(deps) {
|
|
|
154
271
|
catch (error) {
|
|
155
272
|
return {
|
|
156
273
|
ok: false,
|
|
274
|
+
alreadyAbsent: false,
|
|
157
275
|
message: `Could not unregister hive service: ${error instanceof Error ? error.message : "unknown error"}.`
|
|
158
276
|
};
|
|
159
277
|
}
|
|
160
|
-
|
|
278
|
+
// Legacy deregister is best-effort (same posture as install()): it is EXPECTED to fail
|
|
279
|
+
// when no pre-decision-#32 unit exists, so it must never fail the uninstall verdict.
|
|
280
|
+
// Only a current-unit deregister failure may flip `ok` to false.
|
|
281
|
+
await runAll(runner, legacyUninstallCommands(resolvedPlan, uid));
|
|
282
|
+
const { allOk, firstFailure, firstFailureResult } = await runAll(runner, uninstallCommands(resolvedPlan, uid));
|
|
161
283
|
try {
|
|
162
284
|
if (resolvedPlan.unitPath !== "")
|
|
163
285
|
fs.removeFile(resolvedPlan.unitPath);
|
|
286
|
+
const legacyPath = legacyUnitPath(resolvedPlan);
|
|
287
|
+
if (legacyPath !== "")
|
|
288
|
+
fs.removeFile(legacyPath);
|
|
164
289
|
}
|
|
165
290
|
catch {
|
|
166
291
|
// A stale unit file should not block uninstall feedback.
|
|
167
292
|
}
|
|
168
293
|
if (!allOk) {
|
|
294
|
+
// M-2: on macOS, `uninstall` runs stop (launchd `bootout`) before this current-unit
|
|
295
|
+
// `bootout`, so the unit is routinely already gone by the time this call runs - that
|
|
296
|
+
// is a friendly no-op (b-AC-6), not a failure, and must be classified as such rather
|
|
297
|
+
// than flipping the whole verb to exit 1 despite complete success (AC-9). A GENUINE
|
|
298
|
+
// failure (permission denied, manager unreachable, etc.) still fails honestly with
|
|
299
|
+
// the underlying error surfaced.
|
|
300
|
+
if (isAlreadyAbsentFailure(resolvedPlan.manager, firstFailureResult)) {
|
|
301
|
+
return {
|
|
302
|
+
ok: false,
|
|
303
|
+
alreadyAbsent: true,
|
|
304
|
+
message: `hive ${resolvedPlan.manager} unit was already absent (nothing to remove).`
|
|
305
|
+
};
|
|
306
|
+
}
|
|
169
307
|
return {
|
|
170
308
|
ok: false,
|
|
171
|
-
|
|
309
|
+
alreadyAbsent: false,
|
|
310
|
+
message: `Removed hive unit file; a deregister command (${firstFailure?.command ?? "unknown"}) reported an error: ${describeFailure(firstFailureResult)}.`
|
|
172
311
|
};
|
|
173
312
|
}
|
|
174
313
|
return {
|
|
175
314
|
ok: true,
|
|
315
|
+
alreadyAbsent: false,
|
|
176
316
|
message: `hive service unregistered (${scopePhrase(resolvedPlan)}). It will not start on next boot/login.`
|
|
177
317
|
};
|
|
178
318
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/service/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/service/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
export const V1_REQUIRED_PEERS = ["honeycomb"];
|
|
2
|
+
/**
|
|
3
|
+
* A daemon "answered": it responded to its `/health` probe at all. `degraded` counts — honeycomb
|
|
4
|
+
* and nectar BOTH boot degraded by design until a workspace is bound (storage unreachable before
|
|
5
|
+
* the first login), which happens AFTER install/onboarding reaches the login step. Gating
|
|
6
|
+
* readiness on `ok` deadlocked fresh-machine onboarding: the health step polled forever waiting
|
|
7
|
+
* for a state only login can produce. Only an explicit no-response (`unreachable`) — or a daemon
|
|
8
|
+
* doctor has never successfully probed (`unknown`) — reads as not ready.
|
|
9
|
+
*/
|
|
10
|
+
function hasAnswered(health) {
|
|
11
|
+
return health === "ok" || health === "degraded";
|
|
12
|
+
}
|
|
2
13
|
export function isFleetReady(status) {
|
|
3
14
|
if (status.supervisor !== "reachable")
|
|
4
15
|
return false;
|
|
5
|
-
if (status.health
|
|
16
|
+
if (!hasAnswered(status.health))
|
|
6
17
|
return false;
|
|
7
|
-
return V1_REQUIRED_PEERS.every((name) => status.daemons.some((daemon) => daemon.name === name && daemon.health
|
|
18
|
+
return V1_REQUIRED_PEERS.every((name) => status.daemons.some((daemon) => daemon.name === name && hasAnswered(daemon.health)));
|
|
8
19
|
}
|
|
9
20
|
//# sourceMappingURL=fleet-readiness.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fleet-readiness.js","sourceRoot":"","sources":["../../src/shared/fleet-readiness.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAW,CAAU,CAAC;AAExD,MAAM,UAAU,YAAY,CAAC,MAA2B;IACtD,IAAI,MAAM,CAAC,UAAU,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"fleet-readiness.js","sourceRoot":"","sources":["../../src/shared/fleet-readiness.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAW,CAAU,CAAC;AAExD;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,MAAmB;IACtC,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,UAAU,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAA2B;IACtD,IAAI,MAAM,CAAC,UAAU,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CACtC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CACpF,CAAC;AACJ,CAAC"}
|