@indigoai-us/hq-cli 5.275.0 → 5.277.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 +112 -0
- package/README.md +12 -0
- package/assets/bot-workers/setup/context/USER-GUIDE.md +4 -4
- package/assets/scaffold/core/scripts/hq-delegate-pickup.sh +99 -0
- package/assets/scaffold/core/scripts/hq-delegate-repo.sh +158 -0
- package/assets/scaffold/core/scripts/hq-delegate-resolve.sh +145 -0
- package/assets/scaffold/core/scripts/hq-delegate-secrets.sh +129 -0
- package/assets/scaffold/core/scripts/hq-delegate-transfer.sh +175 -0
- package/assets/scaffold/core/scripts/lib/secret-patterns.sh +58 -0
- package/dist/command-catalog.generated.d.ts +239 -1
- package/dist/command-catalog.generated.js +302 -1
- package/dist/commands/core-checkpoint.d.ts +4 -2
- package/dist/commands/core-checkpoint.js +34 -3
- package/dist/commands/core-command-catalog.d.ts +4 -2
- package/dist/commands/core-command-catalog.js +5 -2
- package/dist/commands/core-delegate.d.ts +6 -0
- package/dist/commands/core-delegate.js +987 -0
- package/dist/commands/core-ontology.js +3 -3
- package/dist/commands/core.js +11 -1
- package/dist/commands/daemon.d.ts +4 -0
- package/dist/commands/daemon.js +175 -2
- package/dist/commands/dm.d.ts +2 -0
- package/dist/commands/dm.js +11 -4
- package/dist/commands/feedback.d.ts +6 -0
- package/dist/commands/feedback.js +86 -37
- package/dist/commands/lanes-accounts.js +44 -2
- package/dist/commands/lanes-message.js +69 -12
- package/dist/commands/lanes-resume.js +2 -0
- package/dist/commands/lanes-shared.d.ts +3 -0
- package/dist/commands/lanes-shared.js +12 -2
- package/dist/commands/lanes.d.ts +5 -1
- package/dist/commands/lanes.js +402 -49
- package/dist/commands/run-feature-telemetry.d.ts +3 -0
- package/dist/commands/run-feature-telemetry.js +6 -0
- package/dist/commands/run.js +3 -2
- package/dist/commands/secrets.d.ts +16 -1
- package/dist/commands/secrets.js +80 -45
- package/dist/commands/sync-mode.d.ts +11 -0
- package/dist/commands/sync-mode.js +30 -0
- package/dist/commands/whoami.d.ts +4 -6
- package/dist/commands/whoami.js +39 -8
- package/dist/fast-core.d.ts +6 -7
- package/dist/fast-core.js +22 -8
- package/dist/fast-scaffold.d.ts +33 -7
- package/dist/fast-scaffold.js +104 -8
- package/dist/index.js +32 -1
- package/dist/lanes-drain-hook.js +154 -7
- package/dist/lib/agent-kit/run/inbox.js +3 -2
- package/dist/lib/billing/plan-lock.d.ts +3 -1
- package/dist/lib/billing/plan-lock.js +7 -1
- package/dist/lib/checkpoint-ontology/apply.d.ts +6 -0
- package/dist/lib/checkpoint-ontology/apply.js +60 -3
- package/dist/lib/checkpoint-ontology/company.d.ts +8 -4
- package/dist/lib/checkpoint-ontology/company.js +15 -7
- package/dist/lib/checkpoint-ontology/plan.d.ts +36 -0
- package/dist/lib/checkpoint-ontology/plan.js +66 -4
- package/dist/lib/checkpoint-ontology/queued-touches.d.ts +32 -0
- package/dist/lib/checkpoint-ontology/queued-touches.js +193 -0
- package/dist/lib/checkpoint-ontology/tree.d.ts +2 -0
- package/dist/lib/checkpoint-ontology/tree.js +34 -0
- package/dist/lib/core-utils/jq-json-serializer.d.ts +5 -0
- package/dist/lib/core-utils/jq-json-serializer.js +10 -0
- package/dist/lib/core-utils/secret-patterns.d.ts +41 -0
- package/dist/lib/core-utils/secret-patterns.js +33 -0
- package/dist/lib/core-utils/timeout-guard-native.d.ts +7 -0
- package/dist/lib/core-utils/timeout-guard-native.js +40 -0
- package/dist/lib/core-utils/timeout-guard.d.ts +3 -3
- package/dist/lib/core-utils/timeout-guard.js +28 -13
- package/dist/lib/daemon/catalog.d.ts +18 -2
- package/dist/lib/daemon/catalog.js +18 -2
- package/dist/lib/daemon/config.d.ts +6 -0
- package/dist/lib/daemon/config.js +15 -2
- package/dist/lib/daemon/requests.d.ts +4 -0
- package/dist/lib/daemon/requests.js +2 -0
- package/dist/lib/daemon/run.js +94 -8
- package/dist/lib/daemon/supervisor.d.ts +8 -0
- package/dist/lib/daemon/supervisor.js +101 -1
- package/dist/lib/daemon/sync-runner.d.ts +58 -0
- package/dist/lib/daemon/sync-runner.js +277 -0
- package/dist/lib/doctor/__testing__/run-doctor.d.ts +8 -0
- package/dist/lib/doctor/__testing__/run-doctor.js +52 -0
- 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/flag-registry.d.ts +12 -7
- package/dist/lib/flag-registry.js +66 -75
- package/dist/lib/flag-snapshot-file.d.ts +20 -0
- package/dist/lib/flag-snapshot-file.js +91 -0
- package/dist/lib/lanes/claude-balance.d.ts +6 -1
- package/dist/lib/lanes/claude-balance.js +46 -8
- package/dist/lib/lanes/config.js +15 -0
- package/dist/lib/lanes/hire-grant-dispatch.d.ts +2 -0
- package/dist/lib/lanes/hire-grant-dispatch.js +41 -0
- package/dist/lib/lanes/index.d.ts +1 -1
- package/dist/lib/lanes/keep-alive.d.ts +3 -0
- package/dist/lib/lanes/keep-alive.js +3 -0
- package/dist/lib/lanes/outpost-dispatch.d.ts +4 -0
- package/dist/lib/lanes/outpost-dispatch.js +11 -2
- package/dist/lib/lanes/reconcile.js +20 -4
- package/dist/lib/lanes/spawn.js +17 -10
- package/dist/lib/lanes/store.js +45 -1
- package/dist/lib/lanes/types.d.ts +30 -1
- package/dist/lib/lanes/types.js +2 -2
- package/dist/lib/lanes/watcher.js +3 -2
- package/dist/lib/process-flag-company-context.d.ts +8 -0
- package/dist/lib/process-flag-company-context.js +67 -0
- package/dist/main.js +3 -1
- package/dist/native-fast-route.d.ts +3 -0
- package/dist/native-fast-route.js +39 -0
- package/dist/secrets-env-fast-path.d.ts +5 -0
- package/dist/secrets-env-fast-path.js +16 -0
- package/dist/secrets-env-fast-route.d.ts +18 -0
- package/dist/secrets-env-fast-route.js +54 -0
- package/dist/utils/cli-telemetry.d.ts +26 -2
- package/dist/utils/cli-telemetry.js +178 -3
- package/dist/utils/hq-root-resolver.d.ts +13 -0
- package/dist/utils/hq-root-resolver.js +103 -0
- package/dist/utils/scaffold-fast-import-guard.js +6 -1
- package/dist/utils/vault-api.d.ts +8 -0
- package/dist/utils/vault-api.js +13 -1
- package/package.json +2 -2
|
@@ -130,6 +130,10 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
130
130
|
return {
|
|
131
131
|
...status,
|
|
132
132
|
effective_home: status.home,
|
|
133
|
+
...(status.auth_state === "home_missing" ? {
|
|
134
|
+
error: "home_missing",
|
|
135
|
+
fix_command: `hq lanes accounts set-home ${provider} ${status.id} <host-home>`,
|
|
136
|
+
} : {}),
|
|
133
137
|
model: accountCfg?.model ?? null,
|
|
134
138
|
effort: accountCfg?.effort ?? null,
|
|
135
139
|
effective_model: model ?? null,
|
|
@@ -165,6 +169,7 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
165
169
|
// Retain the established response field for clients; balancing is now
|
|
166
170
|
// unconditional, so this compatibility value is always true.
|
|
167
171
|
const balanceGateEnabled = true;
|
|
172
|
+
const recentUsageEnabled = await deps.readClaudeAccountBalanceSignalsEnabled(ctx);
|
|
168
173
|
const loads = accountLoadsForReport({ hosts: loaded.snapshots, config });
|
|
169
174
|
const suggestions = planClaudeBalanceMoves({ hosts: loaded.snapshots, config });
|
|
170
175
|
const selections = loaded.snapshots.map((host) => {
|
|
@@ -173,6 +178,8 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
173
178
|
hosts: loaded.snapshots,
|
|
174
179
|
targetHost: host.capacity.host,
|
|
175
180
|
config,
|
|
181
|
+
recentUsageEnabled,
|
|
182
|
+
now: ctx.now(),
|
|
176
183
|
unavailableHosts: loaded.unavailableHosts,
|
|
177
184
|
});
|
|
178
185
|
return {
|
|
@@ -192,11 +199,19 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
192
199
|
});
|
|
193
200
|
const accounts = Object.keys(config.providers.claude.accounts).sort().map((account) => {
|
|
194
201
|
const load = loads.find((row) => row.account === account);
|
|
202
|
+
const currentStatus = loaded.snapshots[0]?.capacity.providers.claude.accounts[account];
|
|
203
|
+
const currentHomeMissing = config.providers.claude.accounts[account]?.enabled === true &&
|
|
204
|
+
currentStatus?.auth_state === "home_missing";
|
|
195
205
|
return {
|
|
196
206
|
account,
|
|
197
207
|
enabled: config.providers.claude.accounts[account]?.enabled === true,
|
|
198
208
|
live_lanes: load?.live_lanes ?? 0,
|
|
199
209
|
counts_complete: load?.counts_complete ?? false,
|
|
210
|
+
...(load ? { recent_usage_at: load.recent_usage_at } : {}),
|
|
211
|
+
...(currentHomeMissing ? {
|
|
212
|
+
error: "home_missing",
|
|
213
|
+
fix_command: `hq lanes accounts set-home claude ${account} <host-home>`,
|
|
214
|
+
} : {}),
|
|
200
215
|
hosts: loaded.snapshots.map((host) => {
|
|
201
216
|
const accountStatus = host.capacity.providers.claude.accounts[account];
|
|
202
217
|
const accountLoad = load?.hosts.find((row) => row.host.kind === host.capacity.host.kind && row.host.id === host.capacity.host.id);
|
|
@@ -204,6 +219,11 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
204
219
|
host: host.capacity.host,
|
|
205
220
|
enabled: accountStatus?.enabled ?? false,
|
|
206
221
|
logged_in: accountStatus?.logged_in ?? null,
|
|
222
|
+
...(accountStatus?.auth_state !== undefined ? { auth_state: accountStatus.auth_state } : {}),
|
|
223
|
+
...(accountStatus?.auth_state === "home_missing" ? {
|
|
224
|
+
error: "home_missing",
|
|
225
|
+
fix_command: `hq lanes accounts set-home claude ${account} <host-home>`,
|
|
226
|
+
} : {}),
|
|
207
227
|
live_lanes: accountLoad?.live_lanes ?? null,
|
|
208
228
|
lane_counts: accountLoad?.lane_counts ?? { running: null, queued: null, awaiting_input: null },
|
|
209
229
|
count_source: accountLoad?.count_source ?? "unavailable",
|
|
@@ -251,6 +271,10 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
251
271
|
suggestions,
|
|
252
272
|
...(opts.apply ? { moved, skipped } : {}),
|
|
253
273
|
});
|
|
274
|
+
const currentHostMissing = Object.entries(config.providers.claude.accounts).some(([account, accountConfig]) => accountConfig.enabled &&
|
|
275
|
+
loaded.snapshots[0]?.capacity.providers.claude.accounts[account]?.auth_state === "home_missing");
|
|
276
|
+
if (currentHostMissing)
|
|
277
|
+
process.exitCode = 1;
|
|
254
278
|
}
|
|
255
279
|
async function runAccountsLogin(ctx, providerRaw, accountId, opts) {
|
|
256
280
|
const callerCwd = ctx.callerCwd();
|
|
@@ -276,6 +300,12 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
276
300
|
if (opts.company !== undefined) {
|
|
277
301
|
await resolveSelectedAccountHomeCompany(ctx, opts.company);
|
|
278
302
|
}
|
|
303
|
+
if (process.platform === "linux" &&
|
|
304
|
+
requestedHome === undefined &&
|
|
305
|
+
registeredAccount !== undefined &&
|
|
306
|
+
effectiveAccountHome(registeredAccount, hostname).source !== "host") {
|
|
307
|
+
throw new LanesError("account_host_home_required", `Account ${id} for ${provider} has no home for this Linux host; pass --home <host-home> to store a host-specific home`, { provider, account: id, hostname });
|
|
308
|
+
}
|
|
279
309
|
const homeRaw = requestedHome ??
|
|
280
310
|
(registeredAccount !== undefined
|
|
281
311
|
? effectiveAccountHome(registeredAccount, hostname).home
|
|
@@ -291,10 +321,22 @@ export function createLaneAccountsHandlers(deps) {
|
|
|
291
321
|
existsSync: (p) => fs.existsSync(p),
|
|
292
322
|
});
|
|
293
323
|
const nextAccount = registeredAccount === undefined
|
|
294
|
-
?
|
|
324
|
+
? process.platform === "linux"
|
|
325
|
+
? {
|
|
326
|
+
home: id === "a" ? DEFAULT_ACCOUNT_HOMES[provider] : `~/.${provider}-${id}`,
|
|
327
|
+
hosts: { [hostname]: { home } },
|
|
328
|
+
enabled: true,
|
|
329
|
+
}
|
|
330
|
+
: { home, enabled: true }
|
|
295
331
|
: { ...registeredAccount, enabled: true };
|
|
296
332
|
if (registeredAccount !== undefined && requestedHome !== undefined) {
|
|
297
|
-
if (
|
|
333
|
+
if (process.platform === "linux") {
|
|
334
|
+
nextAccount.hosts = {
|
|
335
|
+
...(registeredAccount.hosts ?? {}),
|
|
336
|
+
[hostname]: { home },
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
else if (home === registeredAccount.home) {
|
|
298
340
|
if (nextAccount.hosts !== undefined) {
|
|
299
341
|
delete nextAccount.hosts[hostname];
|
|
300
342
|
if (Object.keys(nextAccount.hosts).length === 0)
|
|
@@ -9,7 +9,7 @@ import { dropboxInboxHasMessages, drainDropbox, formatDropboxMessages, formatMon
|
|
|
9
9
|
import { isPidAlive, runWatcherLoop, WATCHER_OUT_MAX_BYTES, watcherOutLogPath, writeWatcherDecision } from "../lib/lanes/watcher.js";
|
|
10
10
|
import { laneStories, laneStory, storyWarning } from "../lib/lanes/stories.js";
|
|
11
11
|
import { laneRunDir, probePidRecord, readPidRecord, readProcStarttime, spawnLaneWorker } from "../lib/lanes/spawn.js";
|
|
12
|
-
import { keepAliveExclusion, keepAliveSupersededBy, LANE_SUPERSESSION_LINEAGE_AWARE_FLAG, loadRetiredLaneIds } from "../lib/lanes/keep-alive.js";
|
|
12
|
+
import { keepAliveExclusion, keepAliveSupersededBy, LANE_RUNNING_SUPERSEDED_MESSAGE_DELIVERY_FLAG, LANE_SUPERSESSION_LINEAGE_AWARE_FLAG, loadRetiredLaneIds } from "../lib/lanes/keep-alive.js";
|
|
13
13
|
import { managerStatusGateEnabledForLane } from "../lib/lanes/manager-status-gate.js";
|
|
14
14
|
import { readLanesRegistryFlag } from "../lib/lanes/registry-flag.js";
|
|
15
15
|
import { resolveLaneCompany } from "../lib/lanes/lane-company.js";
|
|
@@ -90,20 +90,20 @@ export function createLaneMessageHandlers(deps) {
|
|
|
90
90
|
company: companyForLane(lane),
|
|
91
91
|
env: ctx.env,
|
|
92
92
|
});
|
|
93
|
-
|
|
93
|
+
let currentLane = readLane(ctx.hqRoot(), lane.lane_id);
|
|
94
94
|
if (currentLane.state === "killed" || currentLane.state === "cancelled") {
|
|
95
95
|
return { lane: currentLane, exclusion: currentLane.state };
|
|
96
96
|
}
|
|
97
97
|
const localLanes = loadAllLanes(ctx.hqRoot());
|
|
98
98
|
let lanes = localLanes;
|
|
99
|
-
|
|
99
|
+
let retiredLaneIds = loadRetiredLaneIds(ctx.hqRoot());
|
|
100
100
|
const dispatchedCallerId = grantContext?.superseded_message_caller_id;
|
|
101
101
|
const dispatchedSessionId = grantContext?.superseded_message_session_id;
|
|
102
|
-
|
|
102
|
+
let dispatchedContextBound = grantContext !== undefined &&
|
|
103
103
|
ctx.isSsmOwnerDispatch() &&
|
|
104
104
|
sameHireGrantSenior(grantContext.expected_senior, currentLane.senior);
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
let dispatchedSessionContext = dispatchedContextBound && currentLane.senior.kind === "session";
|
|
106
|
+
let dispatchedContextAuthorized = dispatchedContextBound && (dispatchedCallerId !== undefined ||
|
|
107
107
|
(dispatchedSessionId !== undefined && dispatchedSessionId === currentLane.senior.id));
|
|
108
108
|
if (dispatchedContextBound && grantContext &&
|
|
109
109
|
(dispatchedCallerId !== undefined || dispatchedSessionContext)) {
|
|
@@ -116,7 +116,61 @@ export function createLaneMessageHandlers(deps) {
|
|
|
116
116
|
merged.set(currentLane.lane_id, currentLane);
|
|
117
117
|
lanes = [...merged.values()];
|
|
118
118
|
}
|
|
119
|
-
|
|
119
|
+
let exclusion = keepAliveExclusion(currentLane, lanes, retiredLaneIds, lineageAware, companyForLane);
|
|
120
|
+
if (exclusion === "superseded" && currentLane.state !== "done" && currentLane.state !== "interrupted") {
|
|
121
|
+
const runningSupersededMessageDeliveryEnabled = await readLanesRegistryFlag(LANE_RUNNING_SUPERSEDED_MESSAGE_DELIVERY_FLAG, { company: companyForLane(currentLane), env: ctx.env });
|
|
122
|
+
if (runningSupersededMessageDeliveryEnabled) {
|
|
123
|
+
const latestLane = readLane(ctx.hqRoot(), currentLane.lane_id);
|
|
124
|
+
if (latestLane.state === "killed" || latestLane.state === "cancelled") {
|
|
125
|
+
return { lane: latestLane, exclusion: latestLane.state };
|
|
126
|
+
}
|
|
127
|
+
const latestLocalLanes = loadAllLanes(ctx.hqRoot());
|
|
128
|
+
currentLane = latestLane;
|
|
129
|
+
let latestLanes = latestLocalLanes;
|
|
130
|
+
dispatchedContextBound =
|
|
131
|
+
grantContext !== undefined &&
|
|
132
|
+
ctx.isSsmOwnerDispatch() &&
|
|
133
|
+
sameHireGrantSenior(grantContext.expected_senior, currentLane.senior);
|
|
134
|
+
dispatchedSessionContext = dispatchedContextBound && currentLane.senior.kind === "session";
|
|
135
|
+
dispatchedContextAuthorized = dispatchedContextBound && (dispatchedCallerId !== undefined ||
|
|
136
|
+
(dispatchedSessionId !== undefined && dispatchedSessionId === currentLane.senior.id));
|
|
137
|
+
if (dispatchedContextBound && grantContext &&
|
|
138
|
+
(dispatchedCallerId !== undefined || dispatchedSessionContext)) {
|
|
139
|
+
const merged = new Map(latestLocalLanes.map((record) => [record.lane_id, record]));
|
|
140
|
+
for (const snapshot of grantContext.hierarchy) {
|
|
141
|
+
const contextLane = keepAliveLaneFromSnapshot(snapshot);
|
|
142
|
+
if (contextLane)
|
|
143
|
+
merged.set(contextLane.lane_id, contextLane);
|
|
144
|
+
}
|
|
145
|
+
merged.set(currentLane.lane_id, currentLane);
|
|
146
|
+
latestLanes = [...merged.values()];
|
|
147
|
+
}
|
|
148
|
+
lanes = latestLanes;
|
|
149
|
+
retiredLaneIds = loadRetiredLaneIds(ctx.hqRoot());
|
|
150
|
+
exclusion = keepAliveExclusion(currentLane, lanes, retiredLaneIds, lineageAware, companyForLane);
|
|
151
|
+
if (exclusion === "superseded" && currentLane.state !== "done" && currentLane.state !== "interrupted") {
|
|
152
|
+
const callerLaneId = dispatchedContextBound ? dispatchedCallerId : undefined;
|
|
153
|
+
const callerSessionId = dispatchedContextBound
|
|
154
|
+
? (dispatchedSessionId === undefined ? null : dispatchedSessionId)
|
|
155
|
+
: undefined;
|
|
156
|
+
const callerMayMessage = callerMayMessageSupersededLane(ctx, currentLane, lanes, lineageAware, companyForLane, callerLaneId, callerSessionId);
|
|
157
|
+
return {
|
|
158
|
+
lane: currentLane,
|
|
159
|
+
exclusion: undefined,
|
|
160
|
+
...(!dispatchedContextAuthorized && callerMayMessage && ctx.env.HQ_LANE_ID?.trim()
|
|
161
|
+
? { supersededMessageCallerId: ctx.env.HQ_LANE_ID.trim() }
|
|
162
|
+
: {}),
|
|
163
|
+
...(callerMayMessage && !dispatchedContextBound && currentLane.senior.kind === "session" &&
|
|
164
|
+
typeof currentLane.senior.id === "string" &&
|
|
165
|
+
currentLane.senior.id.length > 0 &&
|
|
166
|
+
callerMatchesSessionSenior(ctx, currentLane.senior.id)
|
|
167
|
+
? { supersededMessageSessionId: currentLane.senior.id }
|
|
168
|
+
: {}),
|
|
169
|
+
supersededMessageWarning: `A newer lead supersedes this ${currentLane.state} lane; message delivery is allowed while the lane remains active.`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
120
174
|
const callerLaneId = dispatchedContextBound ? dispatchedCallerId : undefined;
|
|
121
175
|
const callerSessionId = dispatchedContextBound
|
|
122
176
|
? (dispatchedSessionId === undefined ? null : dispatchedSessionId)
|
|
@@ -552,11 +606,14 @@ export function createLaneMessageHandlers(deps) {
|
|
|
552
606
|
: mechanism === "dropbox"
|
|
553
607
|
? "awaiting_next_tool_call"
|
|
554
608
|
: "worker_spawned";
|
|
555
|
-
const warning =
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
? `The
|
|
559
|
-
:
|
|
609
|
+
const warning = [
|
|
610
|
+
eligibility.supersededMessageWarning,
|
|
611
|
+
mechanism === "dropbox" && drainHook !== null && !drainHook.registered
|
|
612
|
+
? `The drain hook is not registered in ${drainHook.path}; the running worker will not receive this message. It stays in the inbox and is delivered on the lane's next start.`
|
|
613
|
+
: mechanism === "dropbox" && next.stalled === true
|
|
614
|
+
? `The worker has made no tool call since ${next.stalled_at ?? "an unknown time"} (${next.stalled_reason ?? "stalled"}); delivery waits on its next tool call.`
|
|
615
|
+
: null,
|
|
616
|
+
].filter((message) => message !== undefined && message !== null).join(" ") || null;
|
|
560
617
|
if (!opts.silent)
|
|
561
618
|
printJson({
|
|
562
619
|
ok: true,
|
|
@@ -223,6 +223,7 @@ export function createLaneResumeHandlers(deps) {
|
|
|
223
223
|
...(resumeProfile !== undefined ? { workerProfile: resumeProfile } : {}),
|
|
224
224
|
...(profileRepin !== undefined ? { profileRepin } : {}),
|
|
225
225
|
...(resumeEffort !== undefined ? { effort: resumeEffort } : {}),
|
|
226
|
+
...(hireGrantContext !== undefined ? { grantContext: hireGrantContext } : {}),
|
|
226
227
|
pending: {
|
|
227
228
|
trigger: "resume",
|
|
228
229
|
resumed_from: resumedFrom,
|
|
@@ -252,6 +253,7 @@ export function createLaneResumeHandlers(deps) {
|
|
|
252
253
|
...(resumeProfile !== undefined ? { workerProfile: resumeProfile } : {}),
|
|
253
254
|
...(profileRepin !== undefined ? { profileRepin } : {}),
|
|
254
255
|
...(resumeEffort !== undefined ? { effort: resumeEffort } : {}),
|
|
256
|
+
...(hireGrantContext !== undefined ? { grantContext: hireGrantContext } : {}),
|
|
255
257
|
pending: {
|
|
256
258
|
trigger: "resume",
|
|
257
259
|
resumed_from: resumedFrom,
|
|
@@ -245,9 +245,11 @@ export interface Ctx {
|
|
|
245
245
|
mergeReviewEnabled?: (company: LaneCompanyRef) => boolean | Promise<boolean>;
|
|
246
246
|
}
|
|
247
247
|
export declare const LANE_OUTPOST_LOAD_BALANCING_FLAG = "lanes.outpost-load-balancing";
|
|
248
|
+
export declare const CLAUDE_ACCOUNT_BALANCE_SIGNALS_FLAG = "lanes.claude-account-balance-signals";
|
|
248
249
|
export declare function defaultLanePlacementEnabled(company: LaneCompanyRef | undefined): Promise<boolean>;
|
|
249
250
|
export declare function readLanePlacementEnabled(ctx: Ctx, company: LaneCompanyRef | undefined): Promise<boolean>;
|
|
250
251
|
export declare function processLanePlacementCompany(ctx: Ctx): LaneCompanyRef | undefined;
|
|
252
|
+
export declare function readClaudeAccountBalanceSignalsEnabled(ctx: Ctx, company?: LaneCompanyRef): Promise<boolean>;
|
|
251
253
|
export declare function parsePlacementPolicy(raw: string): LanePlacementPolicy;
|
|
252
254
|
export declare function assertPlacementEnabled(ctx: Ctx, company: LaneCompanyRef | undefined, readPlacementEnabled?: () => Promise<boolean>): Promise<void>;
|
|
253
255
|
/** Match a direct session-senior caller while refusing lane-worker identities. */
|
|
@@ -349,6 +351,7 @@ export interface LaneAccountsHandlerDeps {
|
|
|
349
351
|
to: string;
|
|
350
352
|
}>;
|
|
351
353
|
printJson(value: unknown): void;
|
|
354
|
+
readClaudeAccountBalanceSignalsEnabled(ctx: Ctx): Promise<boolean>;
|
|
352
355
|
reconcileHostFromCtx(ctx: Ctx): ReconcileHost;
|
|
353
356
|
resolveCallerPath(callerCwd: string, filePath: string): string;
|
|
354
357
|
}
|
|
@@ -72,9 +72,9 @@ export function resolveResumeEffort(ctx, lane, input) {
|
|
|
72
72
|
? undefined
|
|
73
73
|
: providerConfig.accounts[accountId];
|
|
74
74
|
const profileDefaultsApply = input.profile?.profile.meta.provider === lane.provider;
|
|
75
|
-
const pinnedModel = lane.model_source === undefined || lane.model_source === "cli" || lane.model_source === "preserved"
|
|
75
|
+
const pinnedModel = lane.pending_settings?.model ?? (lane.model_source === undefined || lane.model_source === "cli" || lane.model_source === "preserved"
|
|
76
76
|
? lane.model
|
|
77
|
-
: undefined;
|
|
77
|
+
: undefined);
|
|
78
78
|
const model = resolveLaneModel({
|
|
79
79
|
cliModel: input.model?.trim() || pinnedModel,
|
|
80
80
|
profileModel: profileDefaultsApply ? input.profile?.profile.meta.model : undefined,
|
|
@@ -90,12 +90,16 @@ export function resolveResumeEffort(ctx, lane, input) {
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
export function recordedResumeEffort(lane) {
|
|
93
|
+
if (lane.pending_settings?.effort !== undefined) {
|
|
94
|
+
return { effort: lane.pending_settings.effort, source: "cli" };
|
|
95
|
+
}
|
|
93
96
|
return {
|
|
94
97
|
...(lane.effort !== undefined ? { effort: lane.effort } : {}),
|
|
95
98
|
source: lane.effort_source ?? "none",
|
|
96
99
|
};
|
|
97
100
|
}
|
|
98
101
|
export const LANE_OUTPOST_LOAD_BALANCING_FLAG = "lanes.outpost-load-balancing";
|
|
102
|
+
export const CLAUDE_ACCOUNT_BALANCE_SIGNALS_FLAG = "lanes.claude-account-balance-signals";
|
|
99
103
|
function lanePlacementFlagErrorCode(error) {
|
|
100
104
|
if (error && typeof error === "object") {
|
|
101
105
|
for (const key of ["code", "error", "name"]) {
|
|
@@ -135,6 +139,12 @@ export function processLanePlacementCompany(ctx) {
|
|
|
135
139
|
return undefined;
|
|
136
140
|
return { slug: context.companySlug, uid: context.companyUid ?? "" };
|
|
137
141
|
}
|
|
142
|
+
export function readClaudeAccountBalanceSignalsEnabled(ctx, company) {
|
|
143
|
+
return readLanesRegistryFlag(CLAUDE_ACCOUNT_BALANCE_SIGNALS_FLAG, {
|
|
144
|
+
company: company ?? processLanePlacementCompany(ctx),
|
|
145
|
+
env: ctx.env,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
138
148
|
export function parsePlacementPolicy(raw) {
|
|
139
149
|
const value = raw.trim();
|
|
140
150
|
if (value === "local")
|
package/dist/commands/lanes.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { Command } from "commander";
|
|
9
9
|
import { type LanesMesh, type SpawnLoginResult } from "./lanes-shared.js";
|
|
10
10
|
export type { LanesMesh, SpawnLoginResult } from "./lanes-shared.js";
|
|
11
|
-
export { LANE_OUTPOST_LOAD_BALANCING_FLAG } from "./lanes-shared.js";
|
|
11
|
+
export { CLAUDE_ACCOUNT_BALANCE_SIGNALS_FLAG, LANE_OUTPOST_LOAD_BALANCING_FLAG } from "./lanes-shared.js";
|
|
12
12
|
export { resolveAnswerChoice } from "./lanes-questions.js";
|
|
13
13
|
import type { OutpostIdentity } from "../lib/lanes/admission-host.js";
|
|
14
14
|
export { OUTPOST_DIR, OUTPOST_ID_PATH, readOutpostIdentity } from "../lib/lanes/admission-host.js";
|
|
@@ -139,5 +139,9 @@ export declare function pickupFailureUpdater(reasonRaw: string, details: Record<
|
|
|
139
139
|
export declare function applyOutpostAccountPickup(hqRoot: string, laneId: string, modelDeps?: KnownModelsDeps): LaneRecord;
|
|
140
140
|
export declare function cancelPendingQuestionsForLane(hqRoot: string, laneId: string, nowIso: string, operatorReason?: string): QuestionRecord[];
|
|
141
141
|
export declare function stopCommittedState(state: LaneRecord["state"]): "cancelled" | "killed";
|
|
142
|
+
/** Stderr notice that `stop` ends a lane for good, naming the resumable path. */
|
|
143
|
+
export declare function stopTerminalWarning(laneId: string): string;
|
|
144
|
+
/** Stderr notice when an interrupted lane has no session to resume from. */
|
|
145
|
+
export declare function interruptNotResumableWarning(laneId: string): string;
|
|
142
146
|
export declare function registerLanesCommand(parent: Command, deps?: LanesCommandDeps): Command;
|
|
143
147
|
//# sourceMappingURL=lanes.d.ts.map
|