@indigoai-us/hq-cli 5.345.15 → 5.345.16
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
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
## [5.345.
|
|
5
|
+
## [5.345.16] — 2026-10-06
|
|
6
6
|
- Route live hook Sentry reports through the fast CLI path.
|
|
7
7
|
|
|
8
|
+
- Claude account model settings are defaults, so explicit lane models remain eligible; explicit account selections on create, resume, and message are recorded as CLI choices.
|
|
8
9
|
- When `hq-anywhere-runtime` is enabled, `hq install --global --runtime claude --via plugin` installs the `hq` plugin from the `indigoai-us/hq-packages` Claude marketplace, and `hq install @indigoai-us/hq-anywhere` installs the Codex pack from that repository. The flag-off path refuses the HQ Anywhere alias without fetching a package source.
|
|
9
10
|
|
|
10
11
|
## [5.345.14] — 2026-10-06
|
|
@@ -518,7 +518,7 @@ export function createLaneMessageHandlers(deps) {
|
|
|
518
518
|
automaticAccountSelection = undefined;
|
|
519
519
|
}
|
|
520
520
|
}
|
|
521
|
-
const profileRefreshAccount = refreshProfileSettings && resumeProfile !== undefined &&
|
|
521
|
+
const profileRefreshAccount = opts.account === undefined && refreshProfileSettings && resumeProfile !== undefined &&
|
|
522
522
|
lane.account_source !== undefined && lane.account_source !== "cli" &&
|
|
523
523
|
resumeProfile.profile.meta.provider === lane.provider
|
|
524
524
|
? resumeProfile.profile.meta.account ?? (resumeProfile.profile.meta.accounts !== undefined &&
|
|
@@ -665,9 +665,10 @@ export function createLaneMessageHandlers(deps) {
|
|
|
665
665
|
// lane (the dropbox mechanism) is refused inside prepareAccountMove.
|
|
666
666
|
move = await prepareAccountMove(ctx, lane, {
|
|
667
667
|
account: opts.account,
|
|
668
|
+
accountSource: "cli",
|
|
668
669
|
cliModel: opts.model?.trim() || undefined,
|
|
669
670
|
...(resumeProfile !== undefined ? { workerProfile: resumeProfile } : {}),
|
|
670
|
-
...(refreshProfileSettings ? { refreshProfileSettings: true
|
|
671
|
+
...(refreshProfileSettings ? { refreshProfileSettings: true } : {}),
|
|
671
672
|
...(resumeEffort !== undefined ? { effort: resumeEffort } : {}),
|
|
672
673
|
...(hireGrantContext !== undefined ? { grantContext: hireGrantContext } : {}),
|
|
673
674
|
pending: {
|
|
@@ -694,6 +695,7 @@ export function createLaneMessageHandlers(deps) {
|
|
|
694
695
|
account: selection.account,
|
|
695
696
|
cliModel: undefined,
|
|
696
697
|
...(automatic.historyReason !== undefined ? { accountHistoryReason: automatic.historyReason } : {}),
|
|
698
|
+
...(automatic.preservedModel !== undefined ? { preservedModel: automatic.preservedModel } : {}),
|
|
697
699
|
...(resumeProfile !== undefined ? { workerProfile: resumeProfile } : {}),
|
|
698
700
|
...(refreshProfileSettings ? { refreshProfileSettings: true, accountSource: "balanced" } : {}),
|
|
699
701
|
...(resumeEffort !== undefined ? { effort: resumeEffort } : {}),
|
|
@@ -746,8 +748,9 @@ export function createLaneMessageHandlers(deps) {
|
|
|
746
748
|
if (resumeProfile !== undefined && !refreshProfileSettings && (opts.account === undefined || keepCurrentAccount)) {
|
|
747
749
|
validateResumeProfileModel(ctx, lane, resumeProfile.profile);
|
|
748
750
|
}
|
|
749
|
-
if (move === null && (resumeProfile !== undefined || resumeEffort !== undefined ||
|
|
751
|
+
if (move === null && (resumeProfile !== undefined || resumeEffort !== undefined || keepCurrentAccount)) {
|
|
750
752
|
lane = recordResumeSetup(ctx, lane, {
|
|
753
|
+
...(keepCurrentAccount ? { accountSource: "cli" } : {}),
|
|
751
754
|
...(resumeProfile !== undefined ? { profile: resumeProfile } : {}),
|
|
752
755
|
...(refreshProfileSettings ? { refreshProfileSettings: true } : {}),
|
|
753
756
|
...(resumeEffort !== undefined ? { effort: resumeEffort } : {}),
|
|
@@ -279,7 +279,7 @@ export function createLaneResumeHandlers(deps) {
|
|
|
279
279
|
...(refreshProfileSettings ? { refreshProfileSettings: true } : {}),
|
|
280
280
|
})
|
|
281
281
|
: undefined;
|
|
282
|
-
const profileRefreshAccount = refreshProfileSettings && resumeProfile !== undefined &&
|
|
282
|
+
const profileRefreshAccount = opts.account === undefined && refreshProfileSettings && resumeProfile !== undefined &&
|
|
283
283
|
lane.account_source !== undefined && lane.account_source !== "cli" &&
|
|
284
284
|
resumeProfile.profile.meta.provider === lane.provider
|
|
285
285
|
? resumeProfile.profile.meta.account ?? (resumeProfile.profile.meta.accounts !== undefined &&
|
|
@@ -346,9 +346,10 @@ export function createLaneResumeHandlers(deps) {
|
|
|
346
346
|
if (opts.account !== undefined && !keepCurrentAccount) {
|
|
347
347
|
move = await prepareAccountMove(ctx, lane, {
|
|
348
348
|
account: opts.account,
|
|
349
|
+
accountSource: "cli",
|
|
349
350
|
cliModel: opts.model?.trim() || undefined,
|
|
350
351
|
...(resumeProfile !== undefined ? { workerProfile: resumeProfile } : {}),
|
|
351
|
-
...(refreshProfileSettings ? { refreshProfileSettings: true
|
|
352
|
+
...(refreshProfileSettings ? { refreshProfileSettings: true } : {}),
|
|
352
353
|
...(profileRepin !== undefined ? { profileRepin } : {}),
|
|
353
354
|
...(resumeEffort !== undefined ? { effort: resumeEffort } : {}),
|
|
354
355
|
...(hireGrantContext !== undefined ? { grantContext: hireGrantContext } : {}),
|
|
@@ -432,6 +433,7 @@ export function createLaneResumeHandlers(deps) {
|
|
|
432
433
|
...(move === null && profileRepin !== undefined ? { profileRepin } : {}),
|
|
433
434
|
...(move === null && resumeEffort !== undefined ? { effort: resumeEffort } : {}),
|
|
434
435
|
...(keepAlive !== undefined ? { keepAlive } : {}),
|
|
436
|
+
...(move === null && keepCurrentAccount ? { accountSource: "cli" } : {}),
|
|
435
437
|
...(move === null && keepCurrentAccount && opts.model !== undefined ? { cliModel: opts.model } : {}),
|
|
436
438
|
...(requestedMeshCompany !== undefined
|
|
437
439
|
? { meshCompany: requestedMeshCompany, threadId: meshThreadId }
|
package/dist/commands/lanes.js
CHANGED
|
@@ -6488,6 +6488,7 @@ function recordResumeSetup(ctx, lane, input) {
|
|
|
6488
6488
|
input.effort === undefined &&
|
|
6489
6489
|
input.keepAlive === undefined &&
|
|
6490
6490
|
input.cliModel === undefined &&
|
|
6491
|
+
input.accountSource === undefined &&
|
|
6491
6492
|
input.meshCompany === undefined &&
|
|
6492
6493
|
input.clearWorkerProfileChangedQueue !== true &&
|
|
6493
6494
|
input.refreshProfileSettings !== true &&
|
|
@@ -6516,7 +6517,11 @@ function recordResumeSetup(ctx, lane, input) {
|
|
|
6516
6517
|
// recorded, so keep-alive may continue it again after this turn.
|
|
6517
6518
|
if (next.keep_alive_blocked_reason === "terminal_state")
|
|
6518
6519
|
next.keep_alive_blocked_reason = undefined;
|
|
6520
|
+
if (input.accountSource !== undefined)
|
|
6521
|
+
next.account_source = input.accountSource;
|
|
6519
6522
|
applyResumeProfileAndEffort(current, next, { ...input, at: ctx.now().toISOString() });
|
|
6523
|
+
if (input.accountSource !== undefined)
|
|
6524
|
+
next.account_source = input.accountSource;
|
|
6520
6525
|
if (input.clearWorkerProfileChangedQueue === true) {
|
|
6521
6526
|
next.queued_reason = undefined;
|
|
6522
6527
|
next.queued_details = undefined;
|
|
@@ -6628,19 +6633,14 @@ async function prepareAccountMove(ctx, lane, input) {
|
|
|
6628
6633
|
}
|
|
6629
6634
|
// The model the moved run would use, resolved the way spawn resolves it:
|
|
6630
6635
|
// the operator's --model, else the lane's own, else the target account's
|
|
6631
|
-
// default, else the provider's. The
|
|
6632
|
-
//
|
|
6633
|
-
// here, before anything is copied. A target that pins a different model
|
|
6634
|
-
// refuses the lane's model unless the operator names one for the move.
|
|
6636
|
+
// default, else the provider's. The target account model is a default, not
|
|
6637
|
+
// a restriction; quota and provider validation use this effective model.
|
|
6635
6638
|
const model = resolveLaneModel({
|
|
6636
6639
|
cliModel: input.cliModel ?? pinnedModel,
|
|
6637
6640
|
profileModel,
|
|
6638
6641
|
accountModel: targetCfg.model,
|
|
6639
6642
|
providerModel: providerCfg.model,
|
|
6640
6643
|
});
|
|
6641
|
-
if (input.cliModel === undefined && lane.model !== undefined && targetCfg.model !== undefined && model !== targetCfg.model) {
|
|
6642
|
-
throw new LanesError("model_unsupported", `Account ${target} pins model ${targetCfg.model}; lane ${laneId} resolves to ${model ?? lane.model}. Pass --model ${targetCfg.model} to move it onto that model`, { provider: lane.provider, account: target, model: model ?? lane.model, account_model: targetCfg.model, lane_id: laneId });
|
|
6643
|
-
}
|
|
6644
6644
|
const block = quotaBlockFor(loadQuotaState(hqRoot), lane.provider, target, model, now);
|
|
6645
6645
|
if (block.blocked) {
|
|
6646
6646
|
throw new LanesError("account_quota_held", `Account ${target} for ${lane.provider} is held${block.quota_reset_at ? ` until ${block.quota_reset_at}` : ""}${block.marker ? ` (${block.marker})` : ""}`, { provider: lane.provider, account: target, quota_reset_at: block.quota_reset_at ?? null, marker: block.marker ?? null, model: model ?? null });
|
|
@@ -6785,26 +6785,26 @@ async function selectAutomaticClaudeResumeAccount(ctx, lane, workerProfile, opti
|
|
|
6785
6785
|
: lane.model_source === undefined || lane.model_source === "cli" || lane.model_source === "preserved"
|
|
6786
6786
|
? lane.model
|
|
6787
6787
|
: undefined;
|
|
6788
|
-
const
|
|
6789
|
-
(lane.model_source === "cli" || lane.model_source === "preserved")
|
|
6790
|
-
? lane.account
|
|
6791
|
-
: undefined;
|
|
6788
|
+
const profileModel = profileDefaultsApply ? profile?.meta.model : undefined;
|
|
6792
6789
|
const quotaModel = resolveLaneModel({
|
|
6793
|
-
cliModel: pinnedModel
|
|
6794
|
-
profileModel
|
|
6795
|
-
accountModel:
|
|
6790
|
+
cliModel: pinnedModel,
|
|
6791
|
+
profileModel,
|
|
6792
|
+
accountModel: currentConfig?.model,
|
|
6796
6793
|
providerModel: config.providers.claude.model,
|
|
6797
6794
|
});
|
|
6798
6795
|
const recordedAccountQuotaHeld = lane.account !== undefined &&
|
|
6799
6796
|
quotaBlockFor(loadQuotaState(hqRoot), "claude", lane.account, quotaModel, ctx.now()).blocked;
|
|
6800
6797
|
const accountNeedsRepair = recordedAccountUnavailable || recordedAccountQuotaHeld;
|
|
6801
6798
|
const repairUnavailableAccount = options.repairUnavailableAccount === true && accountNeedsRepair;
|
|
6802
|
-
const preservedModel = repairUnavailableAccount && lane.model_source === "account"
|
|
6799
|
+
const preservedModel = repairUnavailableAccount && recordedAccountUnavailable && lane.model_source === "account"
|
|
6803
6800
|
? lane.model ?? currentConfig?.model
|
|
6804
6801
|
: undefined;
|
|
6802
|
+
// Repair keeps an account-derived model pinned through the move; plain
|
|
6803
|
+
// automatic rebalancing resolves each candidate's account default itself.
|
|
6804
|
+
const selectionModel = preservedModel ?? pinnedModel ?? profileModel;
|
|
6805
6805
|
const model = resolveLaneModel({
|
|
6806
|
-
cliModel:
|
|
6807
|
-
profileModel
|
|
6806
|
+
cliModel: pinnedModel,
|
|
6807
|
+
profileModel,
|
|
6808
6808
|
accountModel: lane.account === undefined ? undefined : config.providers.claude.accounts[lane.account]?.model,
|
|
6809
6809
|
providerModel: config.providers.claude.model,
|
|
6810
6810
|
});
|
|
@@ -6824,9 +6824,7 @@ async function selectAutomaticClaudeResumeAccount(ctx, lane, workerProfile, opti
|
|
|
6824
6824
|
allowedAccounts?.includes(lane.account) &&
|
|
6825
6825
|
currentConfig?.enabled === true &&
|
|
6826
6826
|
currentTargetAccount?.enabled === true &&
|
|
6827
|
-
currentTargetAccount.logged_in === true
|
|
6828
|
-
(model === undefined || currentConfig.model === undefined || currentConfig.model === model ||
|
|
6829
|
-
lane.account === recordedModelAccount))
|
|
6827
|
+
currentTargetAccount.logged_in === true)
|
|
6830
6828
|
return undefined;
|
|
6831
6829
|
const selectionInput = {
|
|
6832
6830
|
hosts: balanceHosts.snapshots,
|
|
@@ -6835,8 +6833,7 @@ async function selectAutomaticClaudeResumeAccount(ctx, lane, workerProfile, opti
|
|
|
6835
6833
|
quotaState: loadQuotaState(hqRoot),
|
|
6836
6834
|
recentUsageEnabled: await readClaudeAccountBalanceSignalsEnabled(ctx, lane.company ?? undefined),
|
|
6837
6835
|
now: ctx.now(),
|
|
6838
|
-
...(
|
|
6839
|
-
...(recordedModelAccount !== undefined ? { recordedModelAccount } : {}),
|
|
6836
|
+
...(selectionModel !== undefined ? { model: selectionModel } : {}),
|
|
6840
6837
|
unavailableHosts: balanceHosts.unavailableHosts,
|
|
6841
6838
|
};
|
|
6842
6839
|
let selected;
|
|
@@ -6853,7 +6850,7 @@ async function selectAutomaticClaudeResumeAccount(ctx, lane, workerProfile, opti
|
|
|
6853
6850
|
Array.isArray(err.details.account_reasons)
|
|
6854
6851
|
? err.details.account_reasons.filter((reason) => reason !== null && typeof reason === "object" && !Array.isArray(reason))
|
|
6855
6852
|
: [];
|
|
6856
|
-
const unavailablePinReasons = new Set(["disabled", "home_missing", "not_logged_in", "
|
|
6853
|
+
const unavailablePinReasons = new Set(["disabled", "home_missing", "not_logged_in", "quota_held"]);
|
|
6857
6854
|
const everyProfileAccountUnavailable = profilePin !== undefined && profilePin.length > 0 &&
|
|
6858
6855
|
profilePin.every((account) => accountReasons.some((reason) => reason.account === account && typeof reason.reason === "string" && unavailablePinReasons.has(reason.reason)));
|
|
6859
6856
|
if (!everyProfileAccountUnavailable || lane.account === undefined ||
|
|
@@ -76,8 +76,6 @@ export declare function selectClaudeAccount(input: {
|
|
|
76
76
|
config: LanesConfig;
|
|
77
77
|
allowedAccounts?: readonly string[];
|
|
78
78
|
model?: string;
|
|
79
|
-
/** Keep the recorded account eligible for its already-running CLI model. */
|
|
80
|
-
recordedModelAccount?: string;
|
|
81
79
|
quotaState?: QuotaState;
|
|
82
80
|
/** Recent completed-run tiebreak; callers pass the default-off hq-flags result. */
|
|
83
81
|
recentUsageEnabled?: boolean;
|
|
@@ -131,12 +131,7 @@ function buildLoads(input) {
|
|
|
131
131
|
const quotaBlock = input.quotaState === undefined
|
|
132
132
|
? undefined
|
|
133
133
|
: quotaBlockFor(input.quotaState, "claude", account, quotaModel, input.now);
|
|
134
|
-
const ineligible = targetIneligibilityReason(account, configAccounts[account]?.enabled === true, input.allowedAccounts, targetLoad) ?? (
|
|
135
|
-
input.model !== undefined && configuredModel !== undefined && configuredModel !== input.model
|
|
136
|
-
? "model_mismatch"
|
|
137
|
-
: quotaBlock?.blocked === true
|
|
138
|
-
? "quota_held"
|
|
139
|
-
: undefined);
|
|
134
|
+
const ineligible = targetIneligibilityReason(account, configAccounts[account]?.enabled === true, input.allowedAccounts, targetLoad) ?? (quotaBlock?.blocked === true ? "quota_held" : undefined);
|
|
140
135
|
if (ineligible !== undefined)
|
|
141
136
|
skipped.push({ account, host: targetHost, reason: ineligible });
|
|
142
137
|
const knownCounts = hosts.flatMap((host) => host.live_lanes === null ? [] : [host.live_lanes]);
|