@indigoai-us/hq-cli 5.345.180 → 5.345.182
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 +7 -0
- package/dist/commands/bot.js +37 -9
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +204 -201
- package/dist/hq-cloud-sync-runner/package.json +1 -1
- package/dist/lib/bot/fleet-local.d.ts +7 -3
- package/dist/lib/bot/fleet-local.js +171 -53
- 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/sync-core/flag.d.ts +1 -1
- package/dist/lib/sync-core/flag.js +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.182] — 2026-10-30
|
|
6
|
+
- Keep returning clients on the legacy engine until they update to the corrected cloud receiver, and preserve rename/delete convergence when switching sync engines.
|
|
7
|
+
- Local Grok bots now answer the first owner message normally after their welcome instead of introducing themselves again with `/help`.
|
|
8
|
+
|
|
9
|
+
## [5.345.181] — 2026-10-30
|
|
10
|
+
- Local personal and company bots now share one HQ Fleet runtime installation while keeping isolated native profiles and gateway services. Existing local Fleet bots migrate in place without losing profile state.
|
|
11
|
+
|
|
5
12
|
## [5.345.180] — 2026-10-30
|
|
6
13
|
- New `hq channels add <channel> <member...>` and `hq channels remove <channel> <member>`. An owner can now add a personal bot (or a teammate) to a channel from the CLI by @handle, email, or prs_/agt_ uid, so everyone in the channel can @mention it. Before this there was no verb for it, and posting "@bot" into the channel was refused with "No channel member matches". The server's join-first refusal and the owner-or-company-admin rule for adding and removing members are explained in plain words. Feedback e165b286-b059-4d5c-bd44-ac344f00c821.
|
|
7
14
|
- A local bot can now have a model login of its own, so it no longer has to use yours. `hq bot login <name> [--runtime claude|codex]` runs the runtime's own sign-in into `~/.hq/bots/<name>/auth/<runtime>/` (`CLAUDE_CONFIG_DIR` or `CODEX_HOME`). `hq bot logout <name>` signs that login out and deletes the folder. `hq bot set <name> --account <id|default>` points the bot at an existing `hq capacity` account instead. Every model turn uses the chosen login. When that login is missing or its account is gone, the turn does not fall back to your login: the bot replies in the DM saying so, keeps the message pending, and `hq bot status` shows the problem. `hq bot status` now has a `login:` line (default, own, or the account name) and never shows a token.
|
package/dist/commands/bot.js
CHANGED
|
@@ -57,7 +57,7 @@ import { runtimeDisplayName, signInCommand } from "../lib/bot/runtime-sign-in.js
|
|
|
57
57
|
import { classifyRuntimeFailure, runtimeFailureReason } from "../lib/bot/runtime-failure.js";
|
|
58
58
|
import { PROBE_DEFAULT_TIMEOUT_MS, probeBotRuntime } from "../lib/bot/probe.js";
|
|
59
59
|
import { BOT_LOGIN_RUNTIMES, botAuthEnv, botRuntimeAuth, capacityAccountHome, describeBotAuth, formatBotAuth, isBotLoginRuntime, restoreBotSessions, setAsideBotSessions, signInBotRuntime, signOutBotRuntime, withRuntimeAuth, } from "../lib/bot/runtime-auth.js";
|
|
60
|
-
import { BotApi, BotApiError, BOT_RESTORE_DEFAULTS, buildBotLocalConfig, describeBotLocalConfig, orphanBotRunMessage, parseBotLocalConfig, removeOrphanBotDaemon, botDaemonStatus, botDir, botCredsPath, botLogPath, botsRoot, botTokenStateDir, botWorkerRelDir, buildBotDaemonPaths, createBotLogger, deleteBotCreds, installBotDaemon, repairBotDaemonIfStale, healBotDaemonNodeFromJob, introDmText, isBotMemoryMode, botLocalMemoryDir, botMemoryMode, resolveBotMemoryDir, validateBotIntro, validateBotDisplayName, 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, runtimeCrashSinceStart, resolveBotWorker, runBot, runtimeFor, scaffoldBotMemory, scaffoldBotWorker, startBotDaemon, stopBotDaemon, uninstallBotDaemon, validateBotName, writeBotConfig, writeBotCreds, BOT_RUNTIMES, BOT_INTRO_MAX_CHARS, BOT_DISPLAY_NAME_MAX_CHARS, BOT_KICKOFF_MAX_CHARS, detectBotPlatform, withBotLock, localBotRole, remoteBotRole, remoteBotDisplayName, personFacingName, writeCloudDisplayName, setupSlugFor, ASSISTANT_ROLE, HQ_FLEET_RUNTIME_ENGINE_ID, authenticateFleetLocalBot, bootstrapFleetLocalBot, buildSystemPrompt, controlFleetLocalBot, ensureFleetPython, fleetLocalGatewayPid, fleetProviderForRuntime, importFleetLocalMachineCredential, fleetProviderNeedsSignIn, fleetDefaultCompanies, fleetOwnerCompanies, fleetRuntimeIsDefault, refreshFleetLocalInstructions, fleetLocalPromotionRuntime, installPinnedFleetLocalDistribution, readPromptSources, removeFleetLocalBot, } from "../lib/bot/index.js";
|
|
60
|
+
import { BotApi, BotApiError, BOT_RESTORE_DEFAULTS, buildBotLocalConfig, describeBotLocalConfig, orphanBotRunMessage, parseBotLocalConfig, removeOrphanBotDaemon, botDaemonStatus, botDir, botCredsPath, botLogPath, botsRoot, botTokenStateDir, botWorkerRelDir, buildBotDaemonPaths, createBotLogger, deleteBotCreds, installBotDaemon, repairBotDaemonIfStale, healBotDaemonNodeFromJob, introDmText, isBotMemoryMode, botLocalMemoryDir, botMemoryMode, resolveBotMemoryDir, validateBotIntro, validateBotDisplayName, 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, runtimeCrashSinceStart, resolveBotWorker, runBot, runtimeFor, scaffoldBotMemory, scaffoldBotWorker, startBotDaemon, stopBotDaemon, uninstallBotDaemon, validateBotName, writeBotConfig, writeBotCreds, BOT_RUNTIMES, BOT_INTRO_MAX_CHARS, BOT_DISPLAY_NAME_MAX_CHARS, BOT_KICKOFF_MAX_CHARS, detectBotPlatform, withBotLock, localBotRole, remoteBotRole, remoteBotDisplayName, personFacingName, writeCloudDisplayName, setupSlugFor, ASSISTANT_ROLE, HQ_FLEET_RUNTIME_ENGINE_ID, authenticateFleetLocalBot, bootstrapFleetLocalBot, buildSystemPrompt, controlFleetLocalBot, ensureFleetPython, fleetLocalGatewayPid, fleetLocalProfileNeedsAdoption, fleetProviderForRuntime, importFleetLocalMachineCredential, fleetProviderNeedsSignIn, fleetDefaultCompanies, fleetOwnerCompanies, fleetRuntimeIsDefault, refreshFleetLocalInstructions, fleetLocalPromotionRuntime, installPinnedFleetLocalDistribution, readPromptSources, removeFleetLocalBot, } from "../lib/bot/index.js";
|
|
61
61
|
function collectRepeated(value, previous) {
|
|
62
62
|
return [...previous, value];
|
|
63
63
|
}
|
|
@@ -153,7 +153,7 @@ function fleetAuthCommand(name, config) {
|
|
|
153
153
|
return `hq bot auth ${name} --provider ${config.runtime === "grok" ? "grok" : config.runtime === "codex" ? "chatgpt" : "claude"}`;
|
|
154
154
|
}
|
|
155
155
|
function runFleetRuntimeControl(name, config, action, json) {
|
|
156
|
-
if ((action === "start" || action === "restart") && config.fleetAuthPending === true) {
|
|
156
|
+
if ((action === "install" || action === "start" || action === "restart") && config.fleetAuthPending === true) {
|
|
157
157
|
const authCommand = fleetAuthCommand(name, config);
|
|
158
158
|
if (json)
|
|
159
159
|
console.log(JSON.stringify({ ok: false, name, running: false, state: "stopped", needsSignIn: true, authCommand }, null, 2));
|
|
@@ -161,10 +161,10 @@ function runFleetRuntimeControl(name, config, action, json) {
|
|
|
161
161
|
throw Object.assign(new Error(`Sign this bot in first: ${authCommand}`), { expected: true });
|
|
162
162
|
return;
|
|
163
163
|
}
|
|
164
|
-
if (action === "start" || action === "restart") {
|
|
164
|
+
if (action === "install" || action === "start" || action === "restart") {
|
|
165
165
|
refreshFleetLocalInstructions(config.agentUid, fleetBotSystemPrompt(name, config));
|
|
166
166
|
}
|
|
167
|
-
const installService = config.fleetServiceInstallPending === true && (action === "start" || action === "restart");
|
|
167
|
+
const installService = action === "install" || (config.fleetServiceInstallPending === true && (action === "start" || action === "restart"));
|
|
168
168
|
const result = controlFleetLocalBot(config.agentUid, installService ? "install" : action);
|
|
169
169
|
if (installService && result.ok)
|
|
170
170
|
patchBotConfig(botDir(name), { fleetServiceInstallPending: false, enabled: true });
|
|
@@ -434,10 +434,11 @@ async function startFleetRuntimeBot(name, dir, config, output, extra) {
|
|
|
434
434
|
throw Object.assign(new Error(`Sign this bot in first: ${authCommand}`), { expected: true });
|
|
435
435
|
return { running: false, how: "waiting for sign-in" };
|
|
436
436
|
}
|
|
437
|
+
const adopted = await adoptFleetRuntimeProfile(name, dir, config);
|
|
437
438
|
refreshFleetLocalInstructions(config.agentUid, fleetBotSystemPrompt(name, config));
|
|
438
439
|
const before = readBotStatus(dir);
|
|
439
440
|
const alreadyRunning = !!before && before.state === "running" && isPidAlive(before.pid);
|
|
440
|
-
const installService = config.fleetServiceInstallPending === true;
|
|
441
|
+
const installService = adopted || config.fleetServiceInstallPending === true;
|
|
441
442
|
const result = controlFleetLocalBot(config.agentUid, installService ? "install" : alreadyRunning ? "restart" : "start");
|
|
442
443
|
if (installService && result.ok)
|
|
443
444
|
patchBotConfig(dir, { fleetServiceInstallPending: false, enabled: true });
|
|
@@ -459,6 +460,29 @@ async function startFleetRuntimeBot(name, dir, config, output, extra) {
|
|
|
459
460
|
console.log(chalk.yellow(`${name} did not report running within 45s`) + chalk.dim(` logs: ~/.hq-fleet/profiles/${config.agentUid}/logs`));
|
|
460
461
|
return { running, how };
|
|
461
462
|
}
|
|
463
|
+
async function adoptFleetRuntimeProfile(name, dir, config) {
|
|
464
|
+
if (!fleetLocalProfileNeedsAdoption(config.agentUid))
|
|
465
|
+
return false;
|
|
466
|
+
const installation = await installPinnedFleetLocalDistribution();
|
|
467
|
+
const python = await ensureFleetPython();
|
|
468
|
+
const companyScope = effectiveBotKind(config) === "company"
|
|
469
|
+
? effectiveBotCompanies(config)
|
|
470
|
+
: await fleetOwnerCompanies();
|
|
471
|
+
await bootstrapFleetLocalBot({
|
|
472
|
+
agentUid: config.agentUid,
|
|
473
|
+
ownerUid: config.ownerUid,
|
|
474
|
+
hqRoot: config.hqRoot,
|
|
475
|
+
botDir: dir,
|
|
476
|
+
installation,
|
|
477
|
+
systemPrompt: fleetBotSystemPrompt(name, config),
|
|
478
|
+
provider: fleetProviderForRuntime(config.runtime, config.model),
|
|
479
|
+
ownerCompanies: companyScope,
|
|
480
|
+
}, { python, start: false });
|
|
481
|
+
const credentials = botCredsPath(dir);
|
|
482
|
+
if (fs.existsSync(credentials))
|
|
483
|
+
importFleetLocalMachineCredential(config.agentUid, credentials);
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
462
486
|
/**
|
|
463
487
|
* `output`: "json" | "text" print a result; "silent" prints nothing — used
|
|
464
488
|
* when stop is a step inside rm/restart, whose own JSON must be the only
|
|
@@ -2073,7 +2097,8 @@ export function botExists(name) {
|
|
|
2073
2097
|
export async function runBotRestart(nameArg, opts = {}) {
|
|
2074
2098
|
const b = requireBot(nameArg);
|
|
2075
2099
|
if (isFleetRuntimeBot(b.config)) {
|
|
2076
|
-
|
|
2100
|
+
const adopted = await adoptFleetRuntimeProfile(b.name, b.dir, b.config);
|
|
2101
|
+
runFleetRuntimeControl(b.name, b.config, adopted ? "install" : "restart", opts.json === true || opts.output === "json");
|
|
2077
2102
|
return;
|
|
2078
2103
|
}
|
|
2079
2104
|
const running = readBotStatus(b.dir);
|
|
@@ -2094,10 +2119,11 @@ async function runBotAuth(nameArg, opts) {
|
|
|
2094
2119
|
if (opts.apiKey && !apiKey) {
|
|
2095
2120
|
throw Object.assign(new Error("No API key was received on stdin."), { expected: true });
|
|
2096
2121
|
}
|
|
2122
|
+
const adopted = await adoptFleetRuntimeProfile(b.name, b.dir, b.config);
|
|
2097
2123
|
const result = authenticateFleetLocalBot({
|
|
2098
2124
|
agentUid: b.config.agentUid,
|
|
2099
2125
|
provider: opts.provider,
|
|
2100
|
-
...(b.config.fleetAuthPending === true ? { installService: true } : {}),
|
|
2126
|
+
...(adopted || b.config.fleetAuthPending === true ? { installService: true } : {}),
|
|
2101
2127
|
...(opts.model ? { model: opts.model } : {}),
|
|
2102
2128
|
...(apiKey ? { apiKey } : {}),
|
|
2103
2129
|
...(opts.baseUrl ? { baseUrl: opts.baseUrl } : {}),
|
|
@@ -2529,8 +2555,9 @@ async function repairLocalBot(name, api, bot, daemon) {
|
|
|
2529
2555
|
});
|
|
2530
2556
|
createBotLogger(dir)("info", `re-issued machine credentials for ${name} (${bot.agentUid}) on ${localMachineId()}`);
|
|
2531
2557
|
if (isFleetRuntimeBot(config)) {
|
|
2558
|
+
const adopted = await adoptFleetRuntimeProfile(name, dir, config);
|
|
2532
2559
|
importFleetLocalMachineCredential(bot.agentUid, botCredsPath(dir));
|
|
2533
|
-
const restarted = controlFleetLocalBot(bot.agentUid, "restart").ok === true;
|
|
2560
|
+
const restarted = controlFleetLocalBot(bot.agentUid, adopted ? "install" : "restart").ok === true;
|
|
2534
2561
|
return restarted ? "new credentials, HQ Fleet Runtime restarted" : "new credentials; the HQ Fleet Runtime did not restart (hq bot start " + name + ")";
|
|
2535
2562
|
}
|
|
2536
2563
|
if (daemon && process.platform === "darwin") {
|
|
@@ -2782,7 +2809,8 @@ export function registerBotCommand(program) {
|
|
|
2782
2809
|
.action((name, opts) => wrap(async () => {
|
|
2783
2810
|
const b = requireBot(name);
|
|
2784
2811
|
if (isFleetRuntimeBot(b.config)) {
|
|
2785
|
-
|
|
2812
|
+
const adopted = await adoptFleetRuntimeProfile(b.name, b.dir, b.config);
|
|
2813
|
+
runFleetRuntimeControl(b.name, b.config, adopted ? "install" : "start", opts.json === true);
|
|
2786
2814
|
return;
|
|
2787
2815
|
}
|
|
2788
2816
|
await startBot(b.name, b.dir, b.config, opts.json ? "json" : "text");
|