@indigoai-us/hq-cli 5.345.50 → 5.345.52
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/CHANGELOG.md +11 -0
- package/dist/commands/core-hq-session-native.js +2 -2
- package/dist/commands/core-resolve-company-native.js +2 -2
- package/dist/commands/lanes.js +52 -11
- package/dist/commands/secrets.js +2 -2
- package/dist/commands/workers.js +2 -2
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +40293 -13770
- package/dist/hq-cloud-sync-runner/package.json +1 -1
- package/dist/lib/bot/daemon.d.ts +1 -1
- package/dist/lib/bot/daemon.js +35 -29
- package/dist/lib/daemon/install.js +34 -3
- package/dist/lib/doctor/checks/bots.js +3 -8
- package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
- package/dist/lib/flag-registry-worker-source.generated.js +1 -1
- package/dist/lib/lanes/outpost-dispatch.d.ts +1 -0
- package/dist/lib/lanes/outpost-dispatch.js +2 -0
- package/dist/lib/mesh/live/daemon/install.js +28 -15
- package/dist/lib/service-manager/index.d.ts +3 -0
- package/dist/lib/service-manager/index.js +22 -6
- package/dist/lib/service-manager/launchd.d.ts +40 -3
- package/dist/lib/service-manager/launchd.js +106 -5
- package/dist/lib/service-manager/migration-state.d.ts +12 -0
- package/dist/lib/service-manager/migration-state.js +46 -0
- package/dist/lib/service-manager/migration.d.ts +22 -0
- package/dist/lib/service-manager/migration.js +85 -0
- package/dist/lib/service-manager/startup-migration.d.ts +24 -0
- package/dist/lib/service-manager/startup-migration.js +27 -0
- package/dist/lib/service-manager/types.d.ts +3 -0
- package/dist/main.js +22 -0
- package/dist/native-fast-route.d.ts +4 -0
- package/dist/native-fast-route.js +20 -0
- package/dist/utils/resident-package-preload.js +2 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"hq-cli-daemon-sync-runner","type":"module","version":"6.18.
|
|
1
|
+
{"name":"hq-cli-daemon-sync-runner","type":"module","version":"6.18.54","bundleSha256":"3a2ccf7955d7a5be1ab8e9a54e810d55ec7041e1eda534b84eba75e2199ee2f6","formatVersion":1}
|
package/dist/lib/bot/daemon.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export interface BotDaemonDeps {
|
|
|
64
64
|
platform?: BotDaemonPlatform;
|
|
65
65
|
launchctl?: LaunchctlExec;
|
|
66
66
|
uid?: number;
|
|
67
|
-
fsImpl?: Pick<typeof fs, "existsSync" | "writeFileSync" | "mkdirSync" | "unlinkSync"
|
|
67
|
+
fsImpl?: Pick<typeof fs, "existsSync" | "readFileSync" | "writeFileSync" | "mkdirSync" | "unlinkSync"> & Partial<Pick<typeof fs, "chmodSync" | "renameSync">>;
|
|
68
68
|
/** Blocking sleep, injectable for tests. */
|
|
69
69
|
sleepMs?: (ms: number) => void;
|
|
70
70
|
/**
|
package/dist/lib/bot/daemon.js
CHANGED
|
@@ -15,7 +15,7 @@ import * as path from "node:path";
|
|
|
15
15
|
import { spawn } from "node:child_process";
|
|
16
16
|
import { resolveHqBinary, resolveNodeBinary, preferStableHqBinary } from "../mesh/live/daemon/install.js";
|
|
17
17
|
import { botLogPath, launchdLabel } from "./paths.js";
|
|
18
|
-
import { reloadLaunchd } from "../service-manager/launchd.js";
|
|
18
|
+
import { discoverLaunchdIdentity, installLaunchdPlist, launchdProgramArguments, launchdPlistProgramArguments as parsePlistArguments, parseLaunchdCommand, reloadLaunchd } from "../service-manager/launchd.js";
|
|
19
19
|
import { nodeBinaryProblem, preferStableNodeBinary } from "../node-binary.js";
|
|
20
20
|
export function detectBotPlatform(platform = process.platform) {
|
|
21
21
|
if (platform === "darwin")
|
|
@@ -66,6 +66,12 @@ function escapeXml(value) {
|
|
|
66
66
|
.replace(/"/g, """);
|
|
67
67
|
}
|
|
68
68
|
export function renderBotLaunchdPlist(p) {
|
|
69
|
+
const identity = discoverLaunchdIdentity(p.home);
|
|
70
|
+
const args = launchdProgramArguments({
|
|
71
|
+
nodeBinary: p.nodeBinary,
|
|
72
|
+
hqBinary: p.hqBinary,
|
|
73
|
+
launchdLauncherBinary: identity.launcherBinary,
|
|
74
|
+
}, ["bot", "run", p.name]);
|
|
69
75
|
const envRows = [
|
|
70
76
|
["HOME", p.home],
|
|
71
77
|
["PATH", p.pathEntries.join(":")],
|
|
@@ -80,13 +86,9 @@ export function renderBotLaunchdPlist(p) {
|
|
|
80
86
|
<dict>
|
|
81
87
|
<key>Label</key>
|
|
82
88
|
<string>${escapeXml(p.label)}</string>
|
|
83
|
-
<key>ProgramArguments</key>
|
|
89
|
+
${identity.associatedBundleIdentifier ? ` <key>AssociatedBundleIdentifiers</key>\n <array>\n <string>${escapeXml(identity.associatedBundleIdentifier)}</string>\n </array>\n` : ""} <key>ProgramArguments</key>
|
|
84
90
|
<array>
|
|
85
|
-
<string>${escapeXml(
|
|
86
|
-
<string>${escapeXml(p.hqBinary)}</string>
|
|
87
|
-
<string>bot</string>
|
|
88
|
-
<string>run</string>
|
|
89
|
-
<string>${escapeXml(p.name)}</string>
|
|
91
|
+
${args.map((arg) => ` <string>${escapeXml(arg)}</string>`).join("\n")}
|
|
90
92
|
</array>
|
|
91
93
|
<key>WorkingDirectory</key>
|
|
92
94
|
<string>${escapeXml(p.hqRoot ?? p.botDir)}</string>
|
|
@@ -190,16 +192,13 @@ function launchdLoaded(p, deps) {
|
|
|
190
192
|
return deps.launchctl(["print", `${launchdDomain(deps.uid)}/${p.label}`]).ok;
|
|
191
193
|
}
|
|
192
194
|
export function launchdPlistProgramArguments(plist) {
|
|
193
|
-
|
|
194
|
-
if (!block)
|
|
195
|
-
return [];
|
|
196
|
-
return [...block[1].matchAll(/<string>([^<]*)<\/string>/g)].map((m) => m[1]);
|
|
195
|
+
return parsePlistArguments(plist);
|
|
197
196
|
}
|
|
198
197
|
/** The hq script path baked into an installed unit, or null if none. */
|
|
199
198
|
export function installedDaemonHqBinary(p, io = fs) {
|
|
200
199
|
if (io.existsSync(p.plistPath)) {
|
|
201
200
|
const args = launchdPlistProgramArguments(io.readFileSync(p.plistPath, "utf8"));
|
|
202
|
-
return args
|
|
201
|
+
return parseLaunchdCommand(args)?.hq ?? null;
|
|
203
202
|
}
|
|
204
203
|
if (io.existsSync(p.systemdUnitPath)) {
|
|
205
204
|
const unit = io.readFileSync(p.systemdUnitPath, "utf8");
|
|
@@ -212,7 +211,7 @@ export function installedDaemonHqBinary(p, io = fs) {
|
|
|
212
211
|
export function installedDaemonNodeBinary(p, io = fs) {
|
|
213
212
|
if (io.existsSync(p.plistPath)) {
|
|
214
213
|
const args = launchdPlistProgramArguments(io.readFileSync(p.plistPath, "utf8"));
|
|
215
|
-
return args
|
|
214
|
+
return parseLaunchdCommand(args)?.node ?? null;
|
|
216
215
|
}
|
|
217
216
|
if (io.existsSync(p.systemdUnitPath)) {
|
|
218
217
|
const unit = io.readFileSync(p.systemdUnitPath, "utf8");
|
|
@@ -383,19 +382,27 @@ export function installBotDaemon(p, deps = {}) {
|
|
|
383
382
|
io.mkdirSync(path.dirname(p.logPath), { recursive: true, mode: 0o700 });
|
|
384
383
|
if (platform === "darwin") {
|
|
385
384
|
io.mkdirSync(path.dirname(p.plistPath), { recursive: true });
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
385
|
+
const reloadState = { result: null };
|
|
386
|
+
const written = installLaunchdPlist(p.plistPath, p.label, renderBotLaunchdPlist(p), {
|
|
387
|
+
files: {
|
|
388
|
+
existsSync: io.existsSync,
|
|
389
|
+
readFileSync: (file) => io.readFileSync(file, "utf8"),
|
|
390
|
+
writeFileSync: io.writeFileSync,
|
|
391
|
+
...(io.chmodSync ? { chmodSync: io.chmodSync } : {}),
|
|
392
|
+
...(io.renameSync ? { renameSync: io.renameSync } : {}),
|
|
393
|
+
unlinkSync: io.unlinkSync,
|
|
394
|
+
},
|
|
395
|
+
activate: Boolean(deps.launchctl),
|
|
396
|
+
isLoaded: () => launchdLoaded(p, deps),
|
|
397
|
+
...(deps.launchctl ? { reload: () => { reloadState.result = rebootstrapLaunchd(p, deps); return reloadState.result; } } : {}),
|
|
398
|
+
});
|
|
399
|
+
let loaded = written.loaded;
|
|
400
|
+
if (deps.launchctl && reloadState.result) {
|
|
401
|
+
const r = reloadState.result;
|
|
402
|
+
loaded = r.loaded;
|
|
403
|
+
if (!r?.ok) {
|
|
404
|
+
const detail = `launchctl bootstrap failed after ${r?.bootstrapAttempts ?? 0} attempts: ${(r?.error ?? "").slice(0, 200)}`;
|
|
405
|
+
if (r?.loaded) {
|
|
399
406
|
// The previous definition survived the bootout; keep it running.
|
|
400
407
|
deps.launchctl(["kickstart", "-k", `${launchdDomain(deps.uid)}/${p.label}`]);
|
|
401
408
|
}
|
|
@@ -403,14 +410,13 @@ export function installBotDaemon(p, deps = {}) {
|
|
|
403
410
|
platform,
|
|
404
411
|
action: "install",
|
|
405
412
|
installed: true,
|
|
406
|
-
loaded: r
|
|
413
|
+
loaded: r?.loaded ?? false,
|
|
407
414
|
dest: p.plistPath,
|
|
408
|
-
message: r
|
|
415
|
+
message: r?.loaded
|
|
409
416
|
? `Wrote ${p.plistPath} but ${detail}. The previous definition of ${p.label} is still loaded and was restarted; the rewritten plist is not active yet.`
|
|
410
417
|
: `Wrote ${p.plistPath} but ${detail}. ${p.label} is NOT loaded. Load it with: launchctl bootstrap ${launchdDomain(deps.uid)} ${p.plistPath}`,
|
|
411
418
|
};
|
|
412
419
|
}
|
|
413
|
-
loaded = true;
|
|
414
420
|
}
|
|
415
421
|
return {
|
|
416
422
|
platform,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import * as fs from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
-
import { activateLaunchd, deactivateLaunchd, launchdPlistPath, renderLaunchdPlist, } from "../service-manager/launchd.js";
|
|
20
|
+
import { activateLaunchd, deactivateLaunchd, defaultRunCommand, installLaunchdPlist, launchdIsLoaded, launchdPlistPath, renderLaunchdPlist, } from "../service-manager/launchd.js";
|
|
21
21
|
import { activateSystemd, deactivateSystemd, renderSystemdUserUnit, systemdUnitPath, } from "../service-manager/systemd.js";
|
|
22
22
|
import { escapeXml, shellQuote } from "../service-manager/types.js";
|
|
23
23
|
import { readPidLock } from "../mesh/live/daemon/pid-lock.js";
|
|
@@ -251,12 +251,43 @@ export function installDaemonUnit(host, options, deps) {
|
|
|
251
251
|
fs.mkdirSync(path.dirname(plan.unitPath), { recursive: true });
|
|
252
252
|
if (plan.kind !== "systemd-system")
|
|
253
253
|
fs.mkdirSync(path.join(host.daemonDir, "logs"), { recursive: true });
|
|
254
|
-
if (plan.kind === "
|
|
254
|
+
if (plan.kind === "launchd") {
|
|
255
|
+
let plist;
|
|
256
|
+
try {
|
|
257
|
+
plist = installLaunchdPlist(plan.unitPath, DAEMON_LAUNCHD_LABEL, plan.rendered, {
|
|
258
|
+
run: deps.run ?? defaultRunCommand,
|
|
259
|
+
uid: host.uid,
|
|
260
|
+
sleep: deps.sleep,
|
|
261
|
+
isLoaded: () => launchdIsLoaded(DAEMON_LAUNCHD_LABEL, deps.run ?? defaultRunCommand, host.uid),
|
|
262
|
+
files: {
|
|
263
|
+
existsSync: fs.existsSync,
|
|
264
|
+
readFileSync: (file) => fs.readFileSync(file, "utf8"),
|
|
265
|
+
writeFileSync: fs.writeFileSync,
|
|
266
|
+
chmodSync: fs.chmodSync,
|
|
267
|
+
renameSync: fs.renameSync,
|
|
268
|
+
unlinkSync: fs.unlinkSync,
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
return {
|
|
274
|
+
kind: plan.kind,
|
|
275
|
+
unitPath: plan.unitPath,
|
|
276
|
+
installed: fs.existsSync(plan.unitPath),
|
|
277
|
+
running: launchdIsLoaded(DAEMON_LAUNCHD_LABEL, deps.run ?? defaultRunCommand, host.uid),
|
|
278
|
+
error: err instanceof Error ? err.message : String(err),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
if (!plist.loaded)
|
|
282
|
+
return { kind: plan.kind, unitPath: plan.unitPath, installed: true, running: false };
|
|
283
|
+
}
|
|
284
|
+
else if (plan.kind === "schtasks")
|
|
255
285
|
fs.writeFileSync(plan.unitPath, encodeWindowsTaskXml(plan.rendered));
|
|
256
286
|
else
|
|
257
287
|
fs.writeFileSync(plan.unitPath, plan.rendered, { mode: plan.kind === "systemd-system" ? 0o644 : 0o600 });
|
|
258
288
|
try {
|
|
259
|
-
|
|
289
|
+
if (plan.kind !== "launchd")
|
|
290
|
+
activate(plan, host, deps.run, deps.sleep);
|
|
260
291
|
return { kind: plan.kind, unitPath: plan.unitPath, installed: true, running: true };
|
|
261
292
|
}
|
|
262
293
|
catch (err) {
|
|
@@ -10,6 +10,7 @@ import { botsRoot, botDir, launchdLabel } from "../../bot/paths.js";
|
|
|
10
10
|
import { readBotConfig } from "../../bot/config.js";
|
|
11
11
|
import { isPidAlive, readBotStatus } from "../../bot/status.js";
|
|
12
12
|
import { nodeBinaryProblem } from "../../node-binary.js";
|
|
13
|
+
import { launchdPlistProgramArguments, parseLaunchdCommand } from "../../service-manager/launchd.js";
|
|
13
14
|
export const BOTS_FAMILY_ID = "bots";
|
|
14
15
|
export const BOTS_FAMILY_TITLE = "Local bots";
|
|
15
16
|
const DEFAULT_DEPS = {
|
|
@@ -35,14 +36,8 @@ export function checkBots(_context, deps = DEFAULT_DEPS) {
|
|
|
35
36
|
];
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
function launchdPlistArgs(plist) {
|
|
39
|
-
const block = plist.match(/<key>ProgramArguments<\/key>\s*<array>([\s\S]*?)<\/array>/);
|
|
40
|
-
if (!block)
|
|
41
|
-
return [];
|
|
42
|
-
return [...block[1].matchAll(/<string>([^<]*)<\/string>/g)].map((m) => m[1]);
|
|
43
|
-
}
|
|
44
39
|
function launchdPlistHqBinary(plist) {
|
|
45
|
-
return
|
|
40
|
+
return parseLaunchdCommand(launchdPlistProgramArguments(plist))?.hq ?? null;
|
|
46
41
|
}
|
|
47
42
|
function runChecks(deps) {
|
|
48
43
|
const home = deps.home();
|
|
@@ -122,7 +117,7 @@ function runChecks(deps) {
|
|
|
122
117
|
try {
|
|
123
118
|
const text = fs.readFileSync(plistPath, "utf8");
|
|
124
119
|
hqPath = launchdPlistHqBinary(text);
|
|
125
|
-
nodePath =
|
|
120
|
+
nodePath = parseLaunchdCommand(launchdPlistProgramArguments(text))?.node ?? null;
|
|
126
121
|
}
|
|
127
122
|
catch {
|
|
128
123
|
hqPath = null;
|