@indigoai-us/hq-cli 5.131.0 → 5.133.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 +147 -0
- package/dist/command-catalog.generated.d.ts +12 -0
- package/dist/command-catalog.generated.js +16 -0
- package/dist/commands/lanes.d.ts +15 -4
- package/dist/commands/lanes.js +478 -48
- package/dist/commands/mesh.js +24 -2
- package/dist/commands/update.js +1 -1
- package/dist/lib/bot/paths.d.ts +7 -5
- package/dist/lib/bot/paths.js +8 -1
- package/dist/lib/bot/prompt.d.ts +0 -2
- package/dist/lib/bot/prompt.js +5 -11
- package/dist/lib/bot/room-policy.d.ts +1 -24
- package/dist/lib/bot/room-policy.js +2 -35
- package/dist/lib/bot/run.d.ts +7 -8
- package/dist/lib/bot/run.js +21 -33
- package/dist/lib/bot/session.d.ts +1 -1
- package/dist/lib/bot/session.js +1 -1
- package/dist/lib/lanes/accounts.d.ts +6 -0
- package/dist/lib/lanes/accounts.js +2 -1
- package/dist/lib/lanes/config.d.ts +4 -0
- package/dist/lib/lanes/config.js +9 -0
- package/dist/lib/lanes/constants.d.ts +3 -0
- package/dist/lib/lanes/constants.js +3 -0
- package/dist/lib/lanes/index.d.ts +11 -3
- package/dist/lib/lanes/index.js +6 -1
- package/dist/lib/lanes/mesh-events.js +4 -0
- package/dist/lib/lanes/models.d.ts +78 -0
- package/dist/lib/lanes/models.js +205 -0
- package/dist/lib/lanes/move-account.d.ts +56 -0
- package/dist/lib/lanes/move-account.js +193 -0
- package/dist/lib/lanes/provider-rejection.d.ts +86 -0
- package/dist/lib/lanes/provider-rejection.js +258 -0
- package/dist/lib/lanes/quota.d.ts +23 -3
- package/dist/lib/lanes/quota.js +88 -14
- package/dist/lib/lanes/reconcile-install.d.ts +24 -3
- package/dist/lib/lanes/reconcile-install.js +48 -12
- package/dist/lib/lanes/reconcile.d.ts +5 -2
- package/dist/lib/lanes/reconcile.js +135 -13
- package/dist/lib/lanes/spawn.js +26 -5
- package/dist/lib/lanes/store.js +10 -0
- package/dist/lib/lanes/types.d.ts +51 -2
- package/dist/lib/lanes/types.js +5 -3
- package/dist/lib/lanes/watcher.d.ts +27 -0
- package/dist/lib/lanes/watcher.js +68 -5
- package/dist/lib/mesh/live/backfill-held.d.ts +4 -3
- package/dist/lib/mesh/live/backfill-held.js +37 -14
- package/dist/lib/mesh/live/daemon/doctor.d.ts +6 -0
- package/dist/lib/mesh/live/daemon/doctor.js +16 -2
- package/dist/lib/mesh/live/daemon/install.d.ts +12 -0
- package/dist/lib/mesh/live/daemon/install.js +100 -7
- package/dist/lib/mesh/live/daemon/legacy-listen.d.ts +43 -0
- package/dist/lib/mesh/live/daemon/legacy-listen.js +89 -0
- package/dist/lib/mesh/live/daemon/live-cache.d.ts +26 -0
- package/dist/lib/mesh/live/daemon/live-cache.js +116 -0
- package/dist/lib/mesh/live/daemon/presence.d.ts +7 -3
- package/dist/lib/mesh/live/daemon/presence.js +10 -9
- package/dist/lib/mesh/live/daemon/run.d.ts +18 -0
- package/dist/lib/mesh/live/daemon/run.js +65 -6
- package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +31 -0
- package/dist/lib/mesh/live/daemon/work-subscribe.js +124 -0
- package/dist/lib/mesh/live/emit-evidence.d.ts +19 -0
- package/dist/lib/mesh/live/emit-evidence.js +20 -2
- package/dist/lib/work-context/company.d.ts +16 -0
- package/dist/lib/work-context/company.js +46 -14
- package/dist/utils/self-update.js +4 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,115 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.133.0] — 2026-09-22
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Lane follow-ups now probe all enabled, logged-in accounts for an unpinned
|
|
10
|
+
model, preserve the later quota reset and its source, expire abandoned pickup
|
|
11
|
+
validation markers with a terminal reason, and parse Codex's ordinal
|
|
12
|
+
`try again at` reset time.
|
|
13
|
+
|
|
14
|
+
- `hq sync push` no longer fails every file when the target vault was
|
|
15
|
+
provisioned on or after 2026-09-19. Those vaults carry an S3 Object Lock
|
|
16
|
+
default retention rule, and S3 refuses a PutObject into them unless the
|
|
17
|
+
request carries a content checksum; the CLI's declared `@indigoai-us/hq-cloud`
|
|
18
|
+
range still allowed a client that sends none, so an affected push reported
|
|
19
|
+
`400 InvalidRequest: Content-MD5 OR x-amz-checksum- HTTP header is required
|
|
20
|
+
for Put Object requests with Object Lock parameters` on every file. The
|
|
21
|
+
dependency floor now starts at the release that attaches the checksum, so no
|
|
22
|
+
install can resolve a client that cannot write to a locked vault. A CI guard
|
|
23
|
+
holds the floor.
|
|
24
|
+
|
|
25
|
+
- Lane creation and re-parenting now allow depth 3. A depth-3 caller and any
|
|
26
|
+
derived depth 4 lane are refused with `max_lane_depth`.
|
|
27
|
+
|
|
28
|
+
- Question ageing now derives its two-advance cap from the depth-3 lane cap, so
|
|
29
|
+
an unanswered worker-lane question reaches the user after two hourly hops.
|
|
30
|
+
|
|
31
|
+
## [5.132.0] — 2026-09-22
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- `hq lanes resume <lane-id> --account <id>` and `hq lanes message <lane-id>
|
|
36
|
+
--account <id>` move a lane's provider session to another account of the
|
|
37
|
+
same provider and continue it there, with its full history. The claude
|
|
38
|
+
transcript (`projects/<encoded cwd>/<session>.jsonl`, plus the session's
|
|
39
|
+
subagent directory) or the codex rollout
|
|
40
|
+
(`sessions/YYYY/MM/DD/rollout-*-<session>.jsonl`) is copied into the target
|
|
41
|
+
account's home; the source copy stays, and a copy the target already holds
|
|
42
|
+
is refreshed when it differs, so a lane moved back resumes the turns it ran
|
|
43
|
+
elsewhere. Every check runs before anything is copied or written: the lane must not be running (`lane_running`), the
|
|
44
|
+
target must be an account of the lane's provider
|
|
45
|
+
(`account_provider_mismatch`), exist, be enabled, be logged in, hold no
|
|
46
|
+
quota hold (`account_quota_held`), and know the lane's model; a target that
|
|
47
|
+
pins a different model needs `--model <id>` (new on both commands, accepted
|
|
48
|
+
only with `--account`). Grok lanes are refused with
|
|
49
|
+
`provider_session_not_portable`; a missing transcript or rollout with
|
|
50
|
+
`provider_session_missing`, naming the path searched. The record's
|
|
51
|
+
`account` moves, `account_history` gains an `operator_move` entry,
|
|
52
|
+
`last_resume.account` names the account the run started on, and
|
|
53
|
+
`hq lanes show` prints them; a record that changed after the move was
|
|
54
|
+
prepared is refused with `account_move_conflict`. The capacity decision
|
|
55
|
+
runs under the target account's admission lock, and a moved lane holds its
|
|
56
|
+
slot (`pending_resume`) until its spawn claims it, so two moves cannot share
|
|
57
|
+
one free slot. A target at its running cap queues the lane there with
|
|
58
|
+
`pending_resume`, and the reconcile pass resumes the session on the target,
|
|
59
|
+
honouring `--no-compact`. Mesh events for a moved lane carry `account` and
|
|
60
|
+
`account_move`. Credential files are never copied.
|
|
61
|
+
|
|
62
|
+
- A provider-level turn failure is a named lane failure. When the worker's
|
|
63
|
+
stdout carries a codex `turn.failed` event, a Claude error result with an
|
|
64
|
+
HTTP status, or a grok error object, the watcher classifies the lane
|
|
65
|
+
`failed` with `terminal_reason: provider_rejected` and writes the
|
|
66
|
+
provider's message (capped), status, error class, `retryable`, and the
|
|
67
|
+
model and account the run used to `terminal_details`. Such an exit is never
|
|
68
|
+
`interrupted` and never spawns the envelope repair turn. A 429 stays on the
|
|
69
|
+
quota path. `hq lanes show` prints `terminal_reason` and
|
|
70
|
+
`terminal_details`.
|
|
71
|
+
- `hq lanes create --model` is validated against the provider's own model
|
|
72
|
+
list before anything is written: codex from the account home's
|
|
73
|
+
`models_cache.json`, grok from `grok models`, claude from the aliases and
|
|
74
|
+
full-name prefix in `claude --help`. An unknown id is refused with
|
|
75
|
+
`model_unsupported` naming the provider, the value, the source and the
|
|
76
|
+
accepted ids. A provider whose list cannot be read (missing, corrupt, or
|
|
77
|
+
unreadable cache; failed probe) is not validated. Validation runs before
|
|
78
|
+
the mesh thread is ensured and before the admission lock is taken, so a
|
|
79
|
+
refusal leaves nothing behind and a slow provider probe never holds the
|
|
80
|
+
lock. An unpinned create reads the list of every enabled account the
|
|
81
|
+
balanced choice could land on before the lock; the account is still chosen
|
|
82
|
+
under the lock, restricted to the accounts whose list accepted the model,
|
|
83
|
+
so nothing is refused once the mesh thread exists and no probe or catalog
|
|
84
|
+
read runs while the lock is held. A `grok models` or `claude --help` probe that exits nonzero
|
|
85
|
+
is not a catalog, whatever it printed, and skips validation. Every outpost
|
|
86
|
+
lane is validated at pickup on the executing host, after its account
|
|
87
|
+
binds, and fails with `model_unsupported` there; a lane cancelled during
|
|
88
|
+
the pickup probe stays cancelled and is not spawned. A picked-up lane is
|
|
89
|
+
stored ineligible for admission (`pickup_validation_pending`) until its
|
|
90
|
+
account binds, so the reconcile pass cannot spawn it while the probe is
|
|
91
|
+
out, and the failure write refuses an already-terminal or running record
|
|
92
|
+
inside its compare-and-swap.
|
|
93
|
+
- A codex `turn.failed` or grok error with status 429, or with no status and
|
|
94
|
+
a usage-limit or rate-limit message, now reaches the quota path (reset time
|
|
95
|
+
and account hold recorded) instead of ending `interrupted`, and skips the
|
|
96
|
+
envelope repair turn so the hold applies at once; an explicit non-429
|
|
97
|
+
status wins over quota-sounding text. The reconcile pass applies the same
|
|
98
|
+
routing when it recovers a lane whose worker and watcher both died. The
|
|
99
|
+
provider's output is scanned from the tail one line at a time, so a long
|
|
100
|
+
run's events are never all parsed and held at once. A 429 whose message
|
|
101
|
+
names no reset time holds the account for the provider's
|
|
102
|
+
`quota_default_hold_ms` (fifteen minutes unless configured), recorded with
|
|
103
|
+
`reset_source: default_hold`; a message with a reset time keeps that time.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- `hq lanes reconcile install` no longer copies the installing shell's PATH
|
|
108
|
+
into the systemd unit. The unit PATH is, per resolved provider, the
|
|
109
|
+
directory holding the command name and the real binary's directory when a
|
|
110
|
+
symlink points elsewhere, then the hq binary's directory, then the node
|
|
111
|
+
binary's directory, then `/usr/local/bin:/usr/bin:/bin`, deduplicated; directories synced from
|
|
112
|
+
another machine's profile are left out.
|
|
113
|
+
|
|
5
114
|
## [5.131.0] — 2026-09-22
|
|
6
115
|
|
|
7
116
|
### Added
|
|
@@ -19,6 +128,36 @@
|
|
|
19
128
|
|
|
20
129
|
### Fixed
|
|
21
130
|
|
|
131
|
+
## [Unreleased]
|
|
132
|
+
|
|
133
|
+
- `hq mesh daemon install` and `hq mesh daemon run` unload and remove the
|
|
134
|
+
legacy `ai.getindigo.hq-work-mesh-listen` unit (LaunchAgent, systemd user
|
|
135
|
+
unit, or Scheduled Task) so only the daemon subscribes. The daemon writes
|
|
136
|
+
`~/.hq/work-mesh/live-cache.json` and bumps its cursor once per project-view
|
|
137
|
+
push. MQTT reconnect logs once per transition into reconnecting instead of
|
|
138
|
+
on every close. `hq mesh daemon doctor` reports "legacy listener still
|
|
139
|
+
installed" while that unit remains (US-006).
|
|
140
|
+
|
|
141
|
+
## [Unreleased]
|
|
142
|
+
|
|
143
|
+
- Held-event repair no longer treats a later event timestamp as proof that
|
|
144
|
+
metadata belongs to the current session instance. A reused session id stays
|
|
145
|
+
unresolved when the held event's binding episode does not match the current
|
|
146
|
+
one. A CLI self-update now records the verified HQ root and rewrites a
|
|
147
|
+
legacy daemon unit (no `HQ_ROOT`, or `Restart=on-failure`) before restarting
|
|
148
|
+
it, so the new process does not come up with an empty root allowlist.
|
|
149
|
+
|
|
150
|
+
## [Unreleased]
|
|
151
|
+
|
|
152
|
+
- A machine credential (fleet box or local bot) no longer posts mesh events
|
|
153
|
+
with no company. `HQ_SPAWN_COMPANY`, the bot's company, or the identity
|
|
154
|
+
file is sent with the event. When none of those is set, the event is held
|
|
155
|
+
as `needs_company` and `hq mesh daemon doctor` shows the held count.
|
|
156
|
+
A membership probe that a machine token cannot answer leaves the company
|
|
157
|
+
in place and retries, instead of clearing it.
|
|
158
|
+
|
|
159
|
+
## [Unreleased]
|
|
160
|
+
|
|
22
161
|
- Expected caller errors from company resolution, membership, and qmd lookups
|
|
23
162
|
no longer create Sentry issues. Windows filesystem failures remain visible
|
|
24
163
|
and now include redacted path context plus a sync-aware diagnostic.
|
|
@@ -41,6 +180,14 @@
|
|
|
41
180
|
active `cognito-tokens.json` is left unchanged. `hq mesh daemon doctor`
|
|
42
181
|
prints the whoami subject and the subject the daemon is using.
|
|
43
182
|
|
|
183
|
+
### Changed
|
|
184
|
+
|
|
185
|
+
- Local bots can reply to other people and bots in direct messages and in
|
|
186
|
+
connected rooms without an owner-only sender restriction. Each DM
|
|
187
|
+
correspondent has a separate conversation, and the owner's private context
|
|
188
|
+
stays out of other people's conversations. Bots retain their configured
|
|
189
|
+
owner and check suspicious requests before taking sensitive actions.
|
|
190
|
+
|
|
44
191
|
## [5.130.0] — 2026-09-22
|
|
45
192
|
|
|
46
193
|
### Fixed
|
|
@@ -6780,6 +6780,12 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
6780
6780
|
}, {
|
|
6781
6781
|
readonly flags: "--story <id>";
|
|
6782
6782
|
readonly description: "Re-point story attribution from this message";
|
|
6783
|
+
}, {
|
|
6784
|
+
readonly flags: "--account <id>";
|
|
6785
|
+
readonly description: "Move the lane's session to this account of its provider before the message resumes it";
|
|
6786
|
+
}, {
|
|
6787
|
+
readonly flags: "--model <id>";
|
|
6788
|
+
readonly description: "Model for the moved lane (with --account only)";
|
|
6783
6789
|
}, {
|
|
6784
6790
|
readonly flags: "--no-compact";
|
|
6785
6791
|
readonly description: "Skip the resume-time compaction check for this message";
|
|
@@ -6808,6 +6814,12 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
6808
6814
|
}, {
|
|
6809
6815
|
readonly flags: "--story <id>";
|
|
6810
6816
|
readonly description: "Re-point story attribution from this resume";
|
|
6817
|
+
}, {
|
|
6818
|
+
readonly flags: "--account <id>";
|
|
6819
|
+
readonly description: "Move the lane's session to this account of its provider before resuming";
|
|
6820
|
+
}, {
|
|
6821
|
+
readonly flags: "--model <id>";
|
|
6822
|
+
readonly description: "Model for the moved lane (with --account only)";
|
|
6811
6823
|
}, {
|
|
6812
6824
|
readonly flags: "--no-compact";
|
|
6813
6825
|
readonly description: "Skip the resume-time compaction check for this resume";
|
|
@@ -8763,6 +8763,14 @@ export const COMMAND_CATALOG = [
|
|
|
8763
8763
|
"flags": "--story <id>",
|
|
8764
8764
|
"description": "Re-point story attribution from this message"
|
|
8765
8765
|
},
|
|
8766
|
+
{
|
|
8767
|
+
"flags": "--account <id>",
|
|
8768
|
+
"description": "Move the lane's session to this account of its provider before the message resumes it"
|
|
8769
|
+
},
|
|
8770
|
+
{
|
|
8771
|
+
"flags": "--model <id>",
|
|
8772
|
+
"description": "Model for the moved lane (with --account only)"
|
|
8773
|
+
},
|
|
8766
8774
|
{
|
|
8767
8775
|
"flags": "--no-compact",
|
|
8768
8776
|
"description": "Skip the resume-time compaction check for this message"
|
|
@@ -8800,6 +8808,14 @@ export const COMMAND_CATALOG = [
|
|
|
8800
8808
|
"flags": "--story <id>",
|
|
8801
8809
|
"description": "Re-point story attribution from this resume"
|
|
8802
8810
|
},
|
|
8811
|
+
{
|
|
8812
|
+
"flags": "--account <id>",
|
|
8813
|
+
"description": "Move the lane's session to this account of its provider before resuming"
|
|
8814
|
+
},
|
|
8815
|
+
{
|
|
8816
|
+
"flags": "--model <id>",
|
|
8817
|
+
"description": "Model for the moved lane (with --account only)"
|
|
8818
|
+
},
|
|
8803
8819
|
{
|
|
8804
8820
|
"flags": "--no-compact",
|
|
8805
8821
|
"description": "Skip the resume-time compaction check for this resume"
|
package/dist/commands/lanes.d.ts
CHANGED
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import { type OutpostDispatchResult } from "../lib/lanes/outpost-dispatch.js";
|
|
9
9
|
import { emitLaneDecisionEvents, type LaneMesh } from "../lib/lanes/mesh-events.js";
|
|
10
|
-
import { type LaneCompanyRef, type LaneRecord, type QuestionRecord, type ResolvedLaneWorker, type SeniorRef, type LivenessDeps, type MachineIdentity, type RunCommand, type ThrottleDeps } from "../lib/lanes/index.js";
|
|
10
|
+
import { MAX_LANE_DEPTH, type LaneCompanyRef, type LaneRecord, type QuestionRecord, type ResolvedLaneWorker, type SeniorRef, type LivenessDeps, type MachineIdentity, type RunCommand, type ThrottleDeps } from "../lib/lanes/index.js";
|
|
11
11
|
import { questionBodyAbsPath } from "../lib/lanes/questions.js";
|
|
12
12
|
import { type RunCompactionFn } from "../lib/lanes/compaction.js";
|
|
13
|
+
import { type KnownModelsDeps, type ProbeCommand } from "../lib/lanes/models.js";
|
|
13
14
|
import { spawnLaneWorker, type KillProcessFn, type ProveDetachedFn, type SpawnProcessFn } from "../lib/lanes/spawn.js";
|
|
14
15
|
export { spawnLaneWorker };
|
|
15
16
|
export { questionBodyAbsPath };
|
|
16
|
-
export
|
|
17
|
+
export { MAX_LANE_DEPTH };
|
|
17
18
|
export declare const OUTPOST_ID_PATH = "/etc/outpost/outpost-id";
|
|
18
19
|
export declare const OUTPOST_DIR = "/etc/outpost";
|
|
19
20
|
export declare const LANES_RUNS_REL: string;
|
|
@@ -62,6 +63,8 @@ export interface LanesCommandDeps {
|
|
|
62
63
|
presenceConnected?: boolean;
|
|
63
64
|
systemdRoot?: string;
|
|
64
65
|
runSystemctl?: RunCommand;
|
|
66
|
+
/** Provider CLI probe for --model validation; tests inject a fake. */
|
|
67
|
+
probeProvider?: ProbeCommand;
|
|
65
68
|
resolveMachineIdentity?: () => MachineIdentity;
|
|
66
69
|
stageOutpostPayload?: (outpostId: string, bytes: Uint8Array) => Promise<{
|
|
67
70
|
getUrl: string;
|
|
@@ -100,14 +103,22 @@ export declare function composeWorkerBrief(worker: ResolvedLaneWorker, taskBrief
|
|
|
100
103
|
*/
|
|
101
104
|
export declare function composeGeneralBrief(taskBrief: string): string;
|
|
102
105
|
export declare function parseMaxRuntimeSeconds(raw: unknown, workerId: string): number | undefined;
|
|
103
|
-
export declare const PICKUP_TERMINAL_REASONS: readonly ["account_not_logged_in", "unknown_account", "account_disabled"];
|
|
106
|
+
export declare const PICKUP_TERMINAL_REASONS: readonly ["account_not_logged_in", "unknown_account", "account_disabled", "model_unsupported"];
|
|
104
107
|
export declare const DISPATCH_TERMINAL_REASON: "outpost_dispatch_failed";
|
|
105
108
|
export type PickupTerminalReason = (typeof PICKUP_TERMINAL_REASONS)[number];
|
|
109
|
+
/**
|
|
110
|
+
* The CAS updater a pickup failure applies. A lane that is already terminal
|
|
111
|
+
* for any reason (a cancel that landed after the caller's last read, an
|
|
112
|
+
* earlier pickup failure) is returned unchanged: the guard lives inside the
|
|
113
|
+
* same compare-and-swap that writes the failure, so no read-then-write gap
|
|
114
|
+
* can overwrite another writer's terminal decision.
|
|
115
|
+
*/
|
|
116
|
+
export declare function pickupFailureUpdater(reasonRaw: string, details: Record<string, unknown>): (current: LaneRecord) => LaneRecord;
|
|
106
117
|
/**
|
|
107
118
|
* Outpost-side account bind (spec §5.2). Writes a named terminal reason,
|
|
108
119
|
* never a plain `failed`.
|
|
109
120
|
*/
|
|
110
|
-
export declare function applyOutpostAccountPickup(hqRoot: string, laneId: string): LaneRecord;
|
|
121
|
+
export declare function applyOutpostAccountPickup(hqRoot: string, laneId: string, modelDeps?: KnownModelsDeps): LaneRecord;
|
|
111
122
|
export declare function cancelPendingQuestionsForLane(hqRoot: string, laneId: string, nowIso: string, operatorReason?: string): QuestionRecord[];
|
|
112
123
|
export declare function stopCommittedState(state: LaneRecord["state"]): "cancelled" | "killed";
|
|
113
124
|
export declare function registerLanesCommand(parent: Command, deps?: LanesCommandDeps): Command;
|