@indigoai-us/hq-cli 5.161.0 → 5.163.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/CHANGELOG.md +27 -2
- package/dist/command-catalog.generated.d.ts +188 -0
- package/dist/command-catalog.generated.js +235 -0
- package/dist/command-registration-plan.d.ts +7 -0
- package/dist/command-registration-plan.js +1 -0
- package/dist/commands/agent-enroll.d.ts +6 -1
- package/dist/commands/agent-enroll.js +30 -3
- package/dist/commands/agents.js +15 -22
- package/dist/commands/bot.js +56 -6
- package/dist/commands/daemon.d.ts +53 -0
- package/dist/commands/daemon.js +554 -0
- package/dist/commands/lanes.js +10 -1
- package/dist/commands/meetings.js +18 -16
- package/dist/commands/mesh.js +9 -0
- package/dist/lib/daemon/catalog.d.ts +85 -0
- package/dist/lib/daemon/catalog.js +274 -0
- package/dist/lib/daemon/config.d.ts +26 -0
- package/dist/lib/daemon/config.js +85 -0
- package/dist/lib/daemon/handoff.d.ts +53 -0
- package/dist/lib/daemon/handoff.js +136 -0
- package/dist/lib/daemon/install.d.ts +76 -0
- package/dist/lib/daemon/install.js +299 -0
- package/dist/lib/daemon/legacy.d.ts +35 -0
- package/dist/lib/daemon/legacy.js +120 -0
- package/dist/lib/daemon/lock.d.ts +47 -0
- package/dist/lib/daemon/lock.js +138 -0
- package/dist/lib/daemon/machine-type.d.ts +48 -0
- package/dist/lib/daemon/machine-type.js +139 -0
- package/dist/lib/daemon/migrate.d.ts +61 -0
- package/dist/lib/daemon/migrate.js +238 -0
- package/dist/lib/daemon/paths.d.ts +22 -0
- package/dist/lib/daemon/paths.js +42 -0
- package/dist/lib/daemon/remote-control.d.ts +35 -0
- package/dist/lib/daemon/remote-control.js +47 -0
- package/dist/lib/daemon/requests.d.ts +24 -0
- package/dist/lib/daemon/requests.js +63 -0
- package/dist/lib/daemon/run.d.ts +41 -0
- package/dist/lib/daemon/run.js +319 -0
- package/dist/lib/daemon/supervisor.d.ts +87 -0
- package/dist/lib/daemon/supervisor.js +523 -0
- package/dist/lib/daemon/updater.d.ts +39 -0
- package/dist/lib/daemon/updater.js +103 -0
- package/dist/lib/flag-registry.d.ts +7 -1
- package/dist/lib/flag-registry.js +8 -0
- package/dist/lib/lanes/delivery.d.ts +5 -3
- package/dist/lib/lanes/delivery.js +14 -6
- package/dist/lib/lanes/spawn.d.ts +5 -0
- package/dist/lib/lanes/spawn.js +25 -3
- package/dist/lib/lanes/types.d.ts +11 -2
- package/dist/lib/lanes/types.js +11 -0
- package/dist/lib/lanes/watcher.d.ts +2 -2
- package/dist/lib/lanes/watcher.js +2 -2
- package/dist/lib/mesh/live/backoff.d.ts +2 -2
- package/dist/lib/mesh/live/backoff.js +16 -3
- package/dist/lib/mesh/live/daemon/run.d.ts +2 -2
- package/dist/lib/mesh/live/daemon/run.js +5 -2
- package/dist/lib/mesh/live/flush.d.ts +3 -2
- package/dist/lib/mesh/live/flush.js +34 -7
- package/dist/lib/mesh/live/session-events-client.d.ts +2 -0
- package/dist/lib/mesh/live/session-events-client.js +25 -0
- package/dist/lib/service-manager/systemd.d.ts +2 -2
- package/dist/lib/service-manager/systemd.js +1 -1
- package/dist/lib/service-manager/types.d.ts +2 -0
- package/dist/main.d.ts +6 -0
- package/dist/main.js +53 -13
- package/dist/utils/cognito-session.d.ts +4 -0
- package/dist/utils/cognito-session.js +11 -10
- package/dist/utils/plan-gate-error.d.ts +27 -13
- package/dist/utils/plan-gate-error.js +133 -58
- package/dist/utils/self-update.d.ts +9 -0
- package/dist/utils/self-update.js +15 -2
- package/package.json +1 -1
package/dist/commands/bot.js
CHANGED
|
@@ -39,8 +39,10 @@ import { DEFAULT_COGNITO, ensureCognitoToken, resolveDefaultHqRoot, } from "../u
|
|
|
39
39
|
import { peekHqApiKey } from "../utils/resolve-vault-credential.js";
|
|
40
40
|
import { getCompanyUid, resolveCallerPersonUid } from "../utils/vault-api.js";
|
|
41
41
|
import { resolveHqBinary } from "../lib/mesh/live/daemon/install.js";
|
|
42
|
+
import { askDaemonToStart, askDaemonToStop, daemonOwnsProcess, daemonSupervises, daemonWillSupervise, handOffInstallHere, } from "../lib/daemon/handoff.js";
|
|
43
|
+
import { daemonPaths } from "../lib/daemon/paths.js";
|
|
42
44
|
import { runtimeDisplayName } from "../lib/bot/runtime-sign-in.js";
|
|
43
|
-
import { BotApi, BotApiError, BOT_RESTORE_DEFAULTS, buildBotLocalConfig, describeBotLocalConfig, orphanBotRunMessage, parseBotLocalConfig, removeOrphanBotDaemon, botDaemonStatus, botDir, botCredsPath, botLogPath, botsRoot, botTokenStateDir, botWorkerRelDir, buildBotDaemonPaths, createBotLogger, deleteBotCreds, installBotDaemon, repairBotDaemonIfStale, introDmText, isBotMemoryMode, botLocalMemoryDir, botMemoryMode, resolveBotMemoryDir, validateBotIntro, validateBotKickoff, validateBotEffort, validateBotModel, effectiveBotEffort, BOT_EFFORT_LEVELS, DEFAULT_BOT_EFFORT, BOT_MEMORY_MODES, BOT_KINDS, isBotKind, effectiveBotKind, effectiveBotCompanies, normalizeBotCompanies, SETUP_BOT_WORKER_ID, isBotRuntimeId, localNameForRemoteBot, remoteBotRunnability, isPidAlive, listBotWorkerOptions, patchBotConfig, readBotConfig, readBotCredsIdentity, readBotStatus, resolveBotWorker, runBot, runtimeFor, scaffoldBotMemory, scaffoldBotWorker, startBotDaemon, stopBotDaemon, uninstallBotDaemon, validateBotName, writeBotConfig, writeBotCreds, BOT_RUNTIMES, BOT_INTRO_MAX_CHARS, BOT_KICKOFF_MAX_CHARS, } from "../lib/bot/index.js";
|
|
45
|
+
import { BotApi, BotApiError, BOT_RESTORE_DEFAULTS, buildBotLocalConfig, describeBotLocalConfig, orphanBotRunMessage, parseBotLocalConfig, removeOrphanBotDaemon, botDaemonStatus, botDir, botCredsPath, botLogPath, botsRoot, botTokenStateDir, botWorkerRelDir, buildBotDaemonPaths, createBotLogger, deleteBotCreds, installBotDaemon, repairBotDaemonIfStale, introDmText, isBotMemoryMode, botLocalMemoryDir, botMemoryMode, resolveBotMemoryDir, validateBotIntro, validateBotKickoff, validateBotEffort, validateBotModel, effectiveBotEffort, BOT_EFFORT_LEVELS, DEFAULT_BOT_EFFORT, BOT_MEMORY_MODES, BOT_KINDS, isBotKind, effectiveBotKind, effectiveBotCompanies, normalizeBotCompanies, SETUP_BOT_WORKER_ID, isBotRuntimeId, localNameForRemoteBot, remoteBotRunnability, isPidAlive, listBotWorkerOptions, patchBotConfig, readBotConfig, readBotCredsIdentity, readBotStatus, resolveBotWorker, runBot, runtimeFor, scaffoldBotMemory, scaffoldBotWorker, startBotDaemon, stopBotDaemon, uninstallBotDaemon, validateBotName, writeBotConfig, writeBotCreds, BOT_RUNTIMES, BOT_INTRO_MAX_CHARS, BOT_KICKOFF_MAX_CHARS, detectBotPlatform, } from "../lib/bot/index.js";
|
|
44
46
|
function collectRepeated(value, previous) {
|
|
45
47
|
return [...previous, value];
|
|
46
48
|
}
|
|
@@ -74,6 +76,13 @@ export const RESERVED_SETUP_BOT_NAME = "setup";
|
|
|
74
76
|
function daemonDeps() {
|
|
75
77
|
return process.platform === "darwin" ? { launchctl: defaultLaunchctl } : {};
|
|
76
78
|
}
|
|
79
|
+
/** Install the bot's LaunchAgent, unless `hq daemon` runs local bots on this machine. */
|
|
80
|
+
function installBotAgent(p) {
|
|
81
|
+
const handedOff = handOffInstallHere(["bots"]);
|
|
82
|
+
if (handedOff)
|
|
83
|
+
return { platform: detectBotPlatform(), action: "install", installed: true, loaded: true, message: handedOff };
|
|
84
|
+
return installBotDaemon(p, daemonDeps());
|
|
85
|
+
}
|
|
77
86
|
export function listBotNames(root) {
|
|
78
87
|
if (!fs.existsSync(root))
|
|
79
88
|
return [];
|
|
@@ -252,8 +261,22 @@ async function startBot(name, dir, config, output, extra = {}) {
|
|
|
252
261
|
patchBotConfig(dir, { enabled: true });
|
|
253
262
|
const paths = buildBotDaemonPaths({ name, botDir: dir, hqRoot: config.hqRoot });
|
|
254
263
|
const d = botDaemonStatus(paths, daemonDeps());
|
|
264
|
+
const hqDaemon = daemonPaths();
|
|
255
265
|
let how;
|
|
256
|
-
|
|
266
|
+
// A bot created since the daemon last read its plan is the daemon's too,
|
|
267
|
+
// unless its own LaunchAgent runs it.
|
|
268
|
+
if (daemonSupervises(hqDaemon, `bots:${name}`) || (!d.installed && daemonWillSupervise(hqDaemon, `bots:${name}`))) {
|
|
269
|
+
// `hq daemon` runs this bot; starting a copy here would run it twice.
|
|
270
|
+
const before = readBotStatus(dir);
|
|
271
|
+
if (before && isPidAlive(before.pid) && before.state === "running") {
|
|
272
|
+
how = `already running under hq daemon (pid ${before.pid})`;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
askDaemonToStart(hqDaemon, `bots:${name}`);
|
|
276
|
+
how = "started by hq daemon";
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else if (d.installed && process.platform === "darwin") {
|
|
257
280
|
repairBotDaemonIfStale(paths, daemonDeps());
|
|
258
281
|
const r = startBotDaemon(paths, daemonDeps());
|
|
259
282
|
how = r.message;
|
|
@@ -298,6 +321,33 @@ async function stopBot(name, dir, config, output) {
|
|
|
298
321
|
if (hasPromotionHold(dir))
|
|
299
322
|
throw new Error("This bot is held for cloud promotion. Continue its promotion before changing local settings or lifecycle.");
|
|
300
323
|
const paths = buildBotDaemonPaths({ name, botDir: dir, hqRoot: config.hqRoot });
|
|
324
|
+
const hqDaemon = daemonPaths();
|
|
325
|
+
const before = readBotStatus(dir);
|
|
326
|
+
const wasRunning = !!before && isPidAlive(before.pid);
|
|
327
|
+
const supervised = daemonSupervises(hqDaemon, `bots:${name}`);
|
|
328
|
+
// Keep the daemon's copy down either way, so it does not start one as soon as this bot is gone.
|
|
329
|
+
if (supervised)
|
|
330
|
+
askDaemonToStop(hqDaemon, `bots:${name}`);
|
|
331
|
+
// A bot started before the daemon is not the daemon's child; stop it directly below.
|
|
332
|
+
if (supervised && (!wasRunning || daemonOwnsProcess(hqDaemon, `bots:${name}`, before.pid))) {
|
|
333
|
+
// The daemon stops it (escalating to SIGKILL itself) and keeps it down; a
|
|
334
|
+
// kill from here would look like a crash and be restarted.
|
|
335
|
+
const gone = await waitFor(() => {
|
|
336
|
+
const s = readBotStatus(dir);
|
|
337
|
+
return !s || !isPidAlive(s.pid);
|
|
338
|
+
}, 20_000);
|
|
339
|
+
if (output === "silent")
|
|
340
|
+
return;
|
|
341
|
+
if (output === "json") {
|
|
342
|
+
console.log(JSON.stringify({ ok: gone, name, signalled: wasRunning, stopped: gone, how: "stopped by hq daemon" }, null, 2));
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (gone)
|
|
346
|
+
console.log(chalk.green(`${name} stopped`) + chalk.dim(" (by hq daemon)"));
|
|
347
|
+
else
|
|
348
|
+
console.log(chalk.yellow(`${name} did not stop within 20s`) + chalk.dim(` (logs: hq daemon logs bots:${name})`));
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
301
351
|
if (process.platform === "darwin")
|
|
302
352
|
stopBotDaemon(paths, daemonDeps());
|
|
303
353
|
const signalled = stopProcess(dir);
|
|
@@ -540,7 +590,7 @@ export async function runBotCreate(nameArg, opts) {
|
|
|
540
590
|
};
|
|
541
591
|
let daemonMessage = null;
|
|
542
592
|
if (opts.daemon !== false && process.platform === "darwin") {
|
|
543
|
-
const r =
|
|
593
|
+
const r = installBotAgent(buildBotDaemonPaths({ name, botDir: dir, hqRoot }));
|
|
544
594
|
daemonMessage = r.message;
|
|
545
595
|
}
|
|
546
596
|
if (!opts.json) {
|
|
@@ -1304,7 +1354,7 @@ async function adoptRemoteBot(input) {
|
|
|
1304
1354
|
createBotLogger(dir)("info", `adopted ${name} (${bot.agentUid}) on ${localMachineId()} kind=${config.kind}${local ? "" : " (no saved settings; defaults)"} runtime=${config.runtime}`);
|
|
1305
1355
|
let daemonMessage = null;
|
|
1306
1356
|
if (input.daemon && process.platform === "darwin") {
|
|
1307
|
-
daemonMessage =
|
|
1357
|
+
daemonMessage = installBotAgent(buildBotDaemonPaths({ name, botDir: dir, hqRoot: input.hqRoot })).message;
|
|
1308
1358
|
}
|
|
1309
1359
|
return {
|
|
1310
1360
|
config,
|
|
@@ -1407,7 +1457,7 @@ async function repairLocalBot(name, api, bot, daemon) {
|
|
|
1407
1457
|
});
|
|
1408
1458
|
createBotLogger(dir)("info", `re-issued machine credentials for ${name} (${bot.agentUid}) on ${localMachineId()}`);
|
|
1409
1459
|
if (daemon && process.platform === "darwin") {
|
|
1410
|
-
|
|
1460
|
+
installBotAgent(buildBotDaemonPaths({ name, botDir: dir, hqRoot: config.hqRoot }));
|
|
1411
1461
|
}
|
|
1412
1462
|
return "new credentials, startup agent reinstalled";
|
|
1413
1463
|
}
|
|
@@ -1694,7 +1744,7 @@ export function registerBotCommand(program) {
|
|
|
1694
1744
|
.option("--json", "Print machine-readable JSON")
|
|
1695
1745
|
.action((name, opts) => wrap(async () => {
|
|
1696
1746
|
const b = requireBot(name);
|
|
1697
|
-
const r =
|
|
1747
|
+
const r = installBotAgent(buildBotDaemonPaths({ name: b.name, botDir: b.dir, hqRoot: b.config.hqRoot }));
|
|
1698
1748
|
console.log(opts.json ? JSON.stringify({ ok: r.installed, ...r }, null, 2) : r.message);
|
|
1699
1749
|
})());
|
|
1700
1750
|
daemon
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `hq daemon` — one supervisor for every HQ background service on a machine.
|
|
3
|
+
*
|
|
4
|
+
* hq daemon status (same as `hq daemon status`)
|
|
5
|
+
* hq daemon install detect the machine type, install the one OS unit
|
|
6
|
+
* hq daemon run what the OS unit runs; starts the default services
|
|
7
|
+
* hq daemon status [--json]
|
|
8
|
+
* hq daemon logs [unit] [--follow] [--lines N]
|
|
9
|
+
* hq daemon restart [unit] | trigger <unit>
|
|
10
|
+
* hq daemon enable|disable <service...> per-machine overrides
|
|
11
|
+
* hq daemon migrate list the older units it would take over (read-only)
|
|
12
|
+
* hq daemon uninstall [--purge]
|
|
13
|
+
*
|
|
14
|
+
* Hidden from `hq --help` while it rolls out.
|
|
15
|
+
*/
|
|
16
|
+
import type { Command } from "commander";
|
|
17
|
+
import { type LegacyUnit } from "../lib/daemon/legacy.js";
|
|
18
|
+
import type { RunCommand } from "../lib/service-manager/launchd.js";
|
|
19
|
+
export interface DaemonCommandDeps {
|
|
20
|
+
env: NodeJS.ProcessEnv;
|
|
21
|
+
home: string;
|
|
22
|
+
platform: NodeJS.Platform;
|
|
23
|
+
out: (line: string) => void;
|
|
24
|
+
err: (line: string) => void;
|
|
25
|
+
run: RunCommand;
|
|
26
|
+
nodeBinary: string;
|
|
27
|
+
hqBinary: string;
|
|
28
|
+
uid: number;
|
|
29
|
+
isRoot: boolean;
|
|
30
|
+
fileExists: (p: string) => boolean;
|
|
31
|
+
readFile: (p: string) => string;
|
|
32
|
+
legacyUnits: () => LegacyUnit[];
|
|
33
|
+
resolveHqRoot: (flag: string | undefined) => string | undefined;
|
|
34
|
+
/** Home folder of the login user a box's system unit runs as. */
|
|
35
|
+
userHome: (user: string) => string;
|
|
36
|
+
/** The pid is a live `hq daemon run`. */
|
|
37
|
+
daemonAlive: (pid: number) => boolean;
|
|
38
|
+
windowsUser?: string;
|
|
39
|
+
windowsHeadlessLauncher?: string;
|
|
40
|
+
systemUnitDir?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The HQ folder install records: --hq-root, else the CLI's shared resolution
|
|
44
|
+
* (HQ_ROOT, the tree around the current folder, the folder the installer or
|
|
45
|
+
* menubar recorded, the well-known locations). Undefined when none resolves.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveDaemonHqRoot(flag: string | undefined, where: {
|
|
48
|
+
env: NodeJS.ProcessEnv;
|
|
49
|
+
cwd: string;
|
|
50
|
+
home: string;
|
|
51
|
+
}): string | undefined;
|
|
52
|
+
export declare function registerDaemonCommand(program: Command, over?: Partial<DaemonCommandDeps>): Command;
|
|
53
|
+
//# sourceMappingURL=daemon.d.ts.map
|