@indigoai-us/hq-cli 5.192.1 → 5.192.2
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/lanes.d.ts +2 -2
- package/dist/commands/lanes.js +40 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.192.2] — 2026-09-25
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Create, resume, automatic repair, and apply now read
|
|
10
|
+
`lanes.claude-account-balance` from hq-flags. `HQ_FLAG_*` remains the local
|
|
11
|
+
override, and a registry read failure keeps the gate off. The
|
|
12
|
+
`accounts balance --json` report includes `balance_gate_enabled`.
|
|
13
|
+
- `hq lanes accounts balance --apply` now honors each lane's company-scoped
|
|
14
|
+
gate, skips disabled company lanes, and rechecks the gate before moving.
|
|
15
|
+
|
|
5
16
|
## [5.192.1] — 2026-09-25
|
|
6
17
|
|
|
7
18
|
### Fixed
|
package/dist/commands/lanes.d.ts
CHANGED
|
@@ -86,8 +86,8 @@ export interface LanesCommandDeps {
|
|
|
86
86
|
isSsmOwnerDispatch?: () => boolean;
|
|
87
87
|
/** Test seam for changing a lane between pre-lock and locked grant reads. */
|
|
88
88
|
withGrantHireLocks?: typeof withLaneHireLocks;
|
|
89
|
-
/** Test seam for the
|
|
90
|
-
laneClaudeAccountBalanceEnabled?: () => boolean
|
|
89
|
+
/** Test seam for the Claude account-balancing gate. */
|
|
90
|
+
laneClaudeAccountBalanceEnabled?: (company?: LaneCompanyRef | null) => boolean | Promise<boolean>;
|
|
91
91
|
}
|
|
92
92
|
export declare const LANE_OUTPOST_LOAD_BALANCING_FLAG = "lanes.outpost-load-balancing";
|
|
93
93
|
export declare function parseSeniorRef(raw: string): SeniorRef;
|
package/dist/commands/lanes.js
CHANGED
|
@@ -57,8 +57,10 @@ export const LANE_OUTPOST_LOAD_BALANCING_FLAG = "lanes.outpost-load-balancing";
|
|
|
57
57
|
function defaultLanePlacementEnabled() {
|
|
58
58
|
return resolveProcessFlagGate(LANE_OUTPOST_LOAD_BALANCING_FLAG, { fallback: false }, () => false);
|
|
59
59
|
}
|
|
60
|
-
function defaultLaneClaudeAccountBalanceEnabled() {
|
|
61
|
-
|
|
60
|
+
function defaultLaneClaudeAccountBalanceEnabled(company) {
|
|
61
|
+
// Keep the local HQ_FLAG override and the registry reader's fail-closed
|
|
62
|
+
// behavior, matching the lane hire-grants gate.
|
|
63
|
+
return readLanesRegistryFlag(CLAUDE_ACCOUNT_BALANCE_FLAG, { company });
|
|
62
64
|
}
|
|
63
65
|
function defaultLaneHireGrantsEnabled(company) {
|
|
64
66
|
return readLanesRegistryFlag(LANE_HIRE_GRANTS_FLAG, { company });
|
|
@@ -2516,7 +2518,7 @@ async function runCreate(ctx, opts) {
|
|
|
2516
2518
|
}
|
|
2517
2519
|
const allowedAccounts = validatedAccounts.size > 0 ? [...validatedAccounts] : profileAccounts;
|
|
2518
2520
|
let accountSelection;
|
|
2519
|
-
if (provider === "claude" && ctx.laneClaudeAccountBalanceEnabled()) {
|
|
2521
|
+
if (provider === "claude" && await ctx.laneClaudeAccountBalanceEnabled(company)) {
|
|
2520
2522
|
const targetHost = placementHostOverride ?? (outpostId !== undefined
|
|
2521
2523
|
? { kind: "outpost", id: outpostId }
|
|
2522
2524
|
: laneHostFromCtx(ctx));
|
|
@@ -4841,7 +4843,7 @@ async function prepareAccountMove(ctx, lane, input) {
|
|
|
4841
4843
|
async function selectAutomaticClaudeResumeAccount(ctx, lane) {
|
|
4842
4844
|
if (lane.provider !== "claude")
|
|
4843
4845
|
return undefined;
|
|
4844
|
-
if (!ctx.laneClaudeAccountBalanceEnabled()) {
|
|
4846
|
+
if (!await ctx.laneClaudeAccountBalanceEnabled(lane.company)) {
|
|
4845
4847
|
if (lane.account === undefined)
|
|
4846
4848
|
return undefined;
|
|
4847
4849
|
const config = loadLanesConfig(ctx.hqRoot());
|
|
@@ -5245,6 +5247,7 @@ async function applyClaudeBalanceMove(ctx, suggestion) {
|
|
|
5245
5247
|
return { lane_id: suggestion.lane_id, host: suggestion.host, from: suggestion.from, to: suggestion.to, state: suggestion.state };
|
|
5246
5248
|
}
|
|
5247
5249
|
const lane = laneWithRecoveredProviderSession(ctx.hqRoot(), readLane(ctx.hqRoot(), suggestion.lane_id));
|
|
5250
|
+
assertBalanceApplyEnabled(await ctx.laneClaudeAccountBalanceEnabled(lane.company));
|
|
5248
5251
|
if (lane.state === "running") {
|
|
5249
5252
|
throw new LanesError("lane_running", `Lane ${lane.lane_id} is running; balance never moves a running turn`, {
|
|
5250
5253
|
lane_id: lane.lane_id,
|
|
@@ -5273,8 +5276,8 @@ async function applyClaudeBalanceMove(ctx, suggestion) {
|
|
|
5273
5276
|
return { lane_id: moved.lane.lane_id, host: moved.lane.host, from: moved.from ?? suggestion.from, to: moved.to, state: moved.lane.state };
|
|
5274
5277
|
}
|
|
5275
5278
|
async function runClaudeBalanceMoveTarget(ctx, laneId, opts) {
|
|
5276
|
-
assertBalanceApplyEnabled(ctx.laneClaudeAccountBalanceEnabled());
|
|
5277
5279
|
const lane = laneWithRecoveredProviderSession(ctx.hqRoot(), readLane(ctx.hqRoot(), laneId));
|
|
5280
|
+
assertBalanceApplyEnabled(await ctx.laneClaudeAccountBalanceEnabled(lane.company));
|
|
5278
5281
|
assertLaneRunsHereForOperatorMutation(ctx, lane, "balance-move-target");
|
|
5279
5282
|
if (lane.provider !== "claude") {
|
|
5280
5283
|
throw new LanesError("claude_account_balance_provider_mismatch", `Lane ${laneId} does not use Claude`, {
|
|
@@ -6873,11 +6876,30 @@ async function runAccountsBalance(ctx, opts) {
|
|
|
6873
6876
|
accepted: ["claude"],
|
|
6874
6877
|
});
|
|
6875
6878
|
}
|
|
6876
|
-
if (opts.apply)
|
|
6877
|
-
assertBalanceApplyEnabled(ctx.laneClaudeAccountBalanceEnabled());
|
|
6878
6879
|
const hqRoot = ctx.hqRoot();
|
|
6879
6880
|
const config = loadLanesConfig(hqRoot);
|
|
6880
6881
|
const loaded = await loadClaudeBalanceHostSnapshots(ctx, hqRoot, config);
|
|
6882
|
+
const laneBalanceGateEnabled = new Map();
|
|
6883
|
+
const companyBalanceGateEnabled = new Map();
|
|
6884
|
+
const lanes = loaded.snapshots.flatMap((host) => host.lanes);
|
|
6885
|
+
for (const lane of lanes) {
|
|
6886
|
+
const companyKey = JSON.stringify([lane.company?.uid ?? null, lane.company?.slug ?? null]);
|
|
6887
|
+
let enabled = companyBalanceGateEnabled.get(companyKey);
|
|
6888
|
+
if (enabled === undefined) {
|
|
6889
|
+
enabled = await ctx.laneClaudeAccountBalanceEnabled(lane.company);
|
|
6890
|
+
companyBalanceGateEnabled.set(companyKey, enabled);
|
|
6891
|
+
}
|
|
6892
|
+
laneBalanceGateEnabled.set(lane.lane_id, enabled);
|
|
6893
|
+
}
|
|
6894
|
+
// With no lanes there is no tenant scope to resolve, so report and enforce
|
|
6895
|
+
// the unscoped/default gate. Otherwise the report reflects whether any
|
|
6896
|
+
// represented lane company has the gate enabled.
|
|
6897
|
+
if (lanes.length === 0) {
|
|
6898
|
+
companyBalanceGateEnabled.set(JSON.stringify([null, null]), await ctx.laneClaudeAccountBalanceEnabled());
|
|
6899
|
+
}
|
|
6900
|
+
const balanceGateEnabled = [...companyBalanceGateEnabled.values()].some(Boolean);
|
|
6901
|
+
if (opts.apply)
|
|
6902
|
+
assertBalanceApplyEnabled(balanceGateEnabled);
|
|
6881
6903
|
const loads = accountLoadsForReport({ hosts: loaded.snapshots, config });
|
|
6882
6904
|
const suggestions = planClaudeBalanceMoves({ hosts: loaded.snapshots, config });
|
|
6883
6905
|
const selections = loaded.snapshots.map((host) => {
|
|
@@ -6939,6 +6961,16 @@ async function runAccountsBalance(ctx, opts) {
|
|
|
6939
6961
|
});
|
|
6940
6962
|
continue;
|
|
6941
6963
|
}
|
|
6964
|
+
if (laneBalanceGateEnabled.get(suggestion.lane_id) !== true) {
|
|
6965
|
+
skipped.push({
|
|
6966
|
+
lane_id: suggestion.lane_id,
|
|
6967
|
+
host: suggestion.host,
|
|
6968
|
+
from: suggestion.from,
|
|
6969
|
+
to: suggestion.to,
|
|
6970
|
+
reason: "claude_account_balance_disabled",
|
|
6971
|
+
});
|
|
6972
|
+
continue;
|
|
6973
|
+
}
|
|
6942
6974
|
try {
|
|
6943
6975
|
moved.push(await applyClaudeBalanceMove(ctx, suggestion));
|
|
6944
6976
|
}
|
|
@@ -6957,6 +6989,7 @@ async function runAccountsBalance(ctx, opts) {
|
|
|
6957
6989
|
ok: true,
|
|
6958
6990
|
action: "accounts.balance",
|
|
6959
6991
|
provider: "claude",
|
|
6992
|
+
balance_gate_enabled: balanceGateEnabled,
|
|
6960
6993
|
accounts,
|
|
6961
6994
|
selections,
|
|
6962
6995
|
unavailable_hosts: loaded.unavailableHosts,
|