@indigoai-us/hq-cli 5.108.7 → 5.108.9
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 +4 -0
- package/dist/lazy-commands.d.ts +55 -0
- package/dist/lazy-commands.js +68 -0
- package/dist/lib/mesh/live/daemon/index.d.ts +1 -1
- package/dist/lib/mesh/live/daemon/index.js +1 -1
- package/dist/lib/mesh/live/daemon/presence.d.ts +19 -0
- package/dist/lib/mesh/live/daemon/presence.js +57 -6
- package/dist/lib/mesh/live/daemon/run.js +11 -7
- package/dist/main.js +14 -199
- package/dist/register-all.d.ts +32 -0
- package/dist/register-all.js +231 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hot-command manifest for the entrypoint's lazy registration.
|
|
3
|
+
*
|
|
4
|
+
* main.ts used to import the entire ~60-module command graph at module scope,
|
|
5
|
+
* so every invocation paid for every command. That is fine for a human typing
|
|
6
|
+
* one command and ruinous for the calls automation makes in a loop: the
|
|
7
|
+
* hq-sentry agent fleet on an outpost runs `hq secrets` about 39 times a minute
|
|
8
|
+
* (each worker resolves credentials before every external command it executes),
|
|
9
|
+
* and each of those processes spent ~0.75 CPU-seconds importing commands it
|
|
10
|
+
* never ran — around half a core, continuously. Measured on Outpost 2
|
|
11
|
+
* (i-09424eff61920a4ac) 2026-09-05; see register-all.ts for the numbers.
|
|
12
|
+
*
|
|
13
|
+
* A command listed here registers ITSELF and nothing else. Anything not listed
|
|
14
|
+
* — `--help`, a bare `hq`, an unknown command, every other command — falls back
|
|
15
|
+
* to `registerAllCommands`, the complete unchanged graph. That fallback is what
|
|
16
|
+
* makes this safe to extend one command at a time: an entry is a performance
|
|
17
|
+
* opt-in, never a behaviour change, and a command that is absent here is simply
|
|
18
|
+
* as fast as it was before.
|
|
19
|
+
*
|
|
20
|
+
* This mirrors commands/scaffold-fast.ts, which does the same thing for the
|
|
21
|
+
* relocated `hq core …` scripts, and carries the same anti-drift discipline: a
|
|
22
|
+
* parity test registers each entry BOTH ways and asserts the resulting command
|
|
23
|
+
* shape is identical, so a manifest entry cannot silently diverge from the real
|
|
24
|
+
* registration.
|
|
25
|
+
*
|
|
26
|
+
* TO ADD A COMMAND: it must register exactly one top-level command, be
|
|
27
|
+
* registered onto `program` (not onto a subcommand group), and have no other
|
|
28
|
+
* module contributing subcommands to it. The parity test enforces the shape;
|
|
29
|
+
* these three conditions are what make the entry correct in the first place.
|
|
30
|
+
*/
|
|
31
|
+
import type { Command } from "commander";
|
|
32
|
+
export type LazyCommand = {
|
|
33
|
+
/** The top-level token this matches — `hq <name> …`. */
|
|
34
|
+
name: string;
|
|
35
|
+
/** Registers this one command onto `program`, importing only its module. */
|
|
36
|
+
register: (program: Command) => Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The hot paths, in descending order of how often automation calls them.
|
|
40
|
+
*
|
|
41
|
+
* `secrets` and `run` are the two commands HQ's own tooling puts on the inner
|
|
42
|
+
* loop: every fleet worker shells through one of them before each external
|
|
43
|
+
* command, which is exactly the shape that makes eager import expensive.
|
|
44
|
+
*/
|
|
45
|
+
export declare const LAZY_COMMANDS: readonly LazyCommand[];
|
|
46
|
+
/**
|
|
47
|
+
* Resolve `process.argv` to a manifest entry, or null to use the full graph.
|
|
48
|
+
*
|
|
49
|
+
* argv is `[node, hq, <name>, ...rest]`. `hq` declares no program-level options
|
|
50
|
+
* before the command name, so argv[2] is the command token when there is one;
|
|
51
|
+
* `--help`, `--version`, and a bare `hq` all fail the lookup and take the
|
|
52
|
+
* fallback, which is the intended behaviour — help must list every command.
|
|
53
|
+
*/
|
|
54
|
+
export declare function findLazyCommand(argv: readonly string[]): LazyCommand | null;
|
|
55
|
+
//# sourceMappingURL=lazy-commands.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hot-command manifest for the entrypoint's lazy registration.
|
|
3
|
+
*
|
|
4
|
+
* main.ts used to import the entire ~60-module command graph at module scope,
|
|
5
|
+
* so every invocation paid for every command. That is fine for a human typing
|
|
6
|
+
* one command and ruinous for the calls automation makes in a loop: the
|
|
7
|
+
* hq-sentry agent fleet on an outpost runs `hq secrets` about 39 times a minute
|
|
8
|
+
* (each worker resolves credentials before every external command it executes),
|
|
9
|
+
* and each of those processes spent ~0.75 CPU-seconds importing commands it
|
|
10
|
+
* never ran — around half a core, continuously. Measured on Outpost 2
|
|
11
|
+
* (i-09424eff61920a4ac) 2026-09-05; see register-all.ts for the numbers.
|
|
12
|
+
*
|
|
13
|
+
* A command listed here registers ITSELF and nothing else. Anything not listed
|
|
14
|
+
* — `--help`, a bare `hq`, an unknown command, every other command — falls back
|
|
15
|
+
* to `registerAllCommands`, the complete unchanged graph. That fallback is what
|
|
16
|
+
* makes this safe to extend one command at a time: an entry is a performance
|
|
17
|
+
* opt-in, never a behaviour change, and a command that is absent here is simply
|
|
18
|
+
* as fast as it was before.
|
|
19
|
+
*
|
|
20
|
+
* This mirrors commands/scaffold-fast.ts, which does the same thing for the
|
|
21
|
+
* relocated `hq core …` scripts, and carries the same anti-drift discipline: a
|
|
22
|
+
* parity test registers each entry BOTH ways and asserts the resulting command
|
|
23
|
+
* shape is identical, so a manifest entry cannot silently diverge from the real
|
|
24
|
+
* registration.
|
|
25
|
+
*
|
|
26
|
+
* TO ADD A COMMAND: it must register exactly one top-level command, be
|
|
27
|
+
* registered onto `program` (not onto a subcommand group), and have no other
|
|
28
|
+
* module contributing subcommands to it. The parity test enforces the shape;
|
|
29
|
+
* these three conditions are what make the entry correct in the first place.
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* The hot paths, in descending order of how often automation calls them.
|
|
33
|
+
*
|
|
34
|
+
* `secrets` and `run` are the two commands HQ's own tooling puts on the inner
|
|
35
|
+
* loop: every fleet worker shells through one of them before each external
|
|
36
|
+
* command, which is exactly the shape that makes eager import expensive.
|
|
37
|
+
*/
|
|
38
|
+
export const LAZY_COMMANDS = [
|
|
39
|
+
{
|
|
40
|
+
name: "secrets",
|
|
41
|
+
register: async (program) => {
|
|
42
|
+
const { registerSecretsCommand } = await import("./commands/secrets.js");
|
|
43
|
+
registerSecretsCommand(program);
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "run",
|
|
48
|
+
register: async (program) => {
|
|
49
|
+
const { registerRunCommand } = await import("./commands/run.js");
|
|
50
|
+
registerRunCommand(program);
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
/**
|
|
55
|
+
* Resolve `process.argv` to a manifest entry, or null to use the full graph.
|
|
56
|
+
*
|
|
57
|
+
* argv is `[node, hq, <name>, ...rest]`. `hq` declares no program-level options
|
|
58
|
+
* before the command name, so argv[2] is the command token when there is one;
|
|
59
|
+
* `--help`, `--version`, and a bare `hq` all fail the lookup and take the
|
|
60
|
+
* fallback, which is the intended behaviour — help must list every command.
|
|
61
|
+
*/
|
|
62
|
+
export function findLazyCommand(argv) {
|
|
63
|
+
const name = argv[2];
|
|
64
|
+
if (typeof name !== "string")
|
|
65
|
+
return null;
|
|
66
|
+
return LAZY_COMMANDS.find((candidate) => candidate.name === name) ?? null;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=lazy-commands.js.map
|
|
@@ -5,7 +5,7 @@ export { CREDENTIAL_RENEWAL_FRACTION, DEFAULT_REFUSED_RETRY_MS, MAX_RETRY_DELAY_
|
|
|
5
5
|
export type { BoundedTimeoutHandle, Contract3Bundle, CredentialRenewalErrorInfo, CredentialVendFailureKind, CredentialVendPostResult, CredentialsFetcher, PresenceCompany, TimerHost, } from "./credentials.js";
|
|
6
6
|
export { amzDateOf, hex, presignIotWssUrl, rfc3986Encode } from "./presign.js";
|
|
7
7
|
export type { IotCredentials } from "./presign.js";
|
|
8
|
-
export { PresenceClient, backoffDelayMs, buildPresencePayload, defaultMqttConnect, isOwnPresenceTopic, } from "./presence.js";
|
|
8
|
+
export { CLOSE_LOG_ALWAYS_COUNT, CLOSE_LOG_INTERVAL_MS, CONNECT_STABLE_GRACE_MS, PresenceClient, backoffDelayMs, buildPresencePayload, defaultMqttConnect, isOwnPresenceTopic, } from "./presence.js";
|
|
9
9
|
export type { MeshMqttClientLike, MqttConnectFn, MqttConnectionState, PresenceClientOptions, PresencePayload, PresenceRefusal, } from "./presence.js";
|
|
10
10
|
export { defaultDaemonState, patchDaemonState, readDaemonState, writeDaemonState, } from "./state.js";
|
|
11
11
|
export type { DaemonStateFile, PresenceRefusalState } from "./state.js";
|
|
@@ -2,7 +2,7 @@ export { DAEMON_DIRNAME, DAEMON_LOG_MAX_BYTES, DAEMON_LOG_NAME, DAEMON_PID_NAME,
|
|
|
2
2
|
export { acquirePidLock, defaultPidLockDeps, parsePidLock, pidLockStatus, readPidLock, releasePidLock, resolveDaemonDir, } from "./pid-lock.js";
|
|
3
3
|
export { CREDENTIAL_RENEWAL_FRACTION, DEFAULT_REFUSED_RETRY_MS, MAX_RETRY_DELAY_MS, MAX_TIMER_DELAY_MS, MQTT_KEEPALIVE_SECONDS, REALTIME_CREDENTIALS_PATH, REFUSED_RETRY_ENV, CredentialRenewalManager, CredentialVendError, classifyCredentialVendFailure, clampRetryDelayMs, createContract3Fetcher, defaultRefusedRetryMs, extractVendErrorCode, isCredentialVendRefused, normalizeContract3Bundle, parseRetryAfterMs, realTimerHost, refusedRetryDelayMs, renewalDelayMs, scheduleBoundedTimeout, } from "./credentials.js";
|
|
4
4
|
export { amzDateOf, hex, presignIotWssUrl, rfc3986Encode } from "./presign.js";
|
|
5
|
-
export { PresenceClient, backoffDelayMs, buildPresencePayload, defaultMqttConnect, isOwnPresenceTopic, } from "./presence.js";
|
|
5
|
+
export { CLOSE_LOG_ALWAYS_COUNT, CLOSE_LOG_INTERVAL_MS, CONNECT_STABLE_GRACE_MS, PresenceClient, backoffDelayMs, buildPresencePayload, defaultMqttConnect, isOwnPresenceTopic, } from "./presence.js";
|
|
6
6
|
export { defaultDaemonState, patchDaemonState, readDaemonState, writeDaemonState, } from "./state.js";
|
|
7
7
|
export { appendDaemonLog, daemonLogLine, ensureDaemonLog, resolveDaemonAssetDir, rotateDaemonLogIfNeeded, } from "./log.js";
|
|
8
8
|
export { BOARD_REFRESH_INTERVAL_MS, createVaultBoardReader, formatBoardMarkdown, refreshBoundSessionBoards, writeBoardMarkdown, } from "./board-refresh.js";
|
|
@@ -7,11 +7,22 @@
|
|
|
7
7
|
* - Offline is server-only (IoT lifecycle → PresenceIngestFunction)
|
|
8
8
|
* - Never subscribes to thread topics
|
|
9
9
|
* - Reconnects with monotonic full-jitter backoff 1s–60s on close / network
|
|
10
|
+
* - Backoff resets only after the connection stays up past
|
|
11
|
+
* {@link CONNECT_STABLE_GRACE_MS} (broker accept-then-close must not reset)
|
|
10
12
|
* - Server credential refusals use a long retry (default 10m ±20%)
|
|
11
13
|
*/
|
|
12
14
|
import { type IClientOptions, type MqttClient } from "mqtt";
|
|
13
15
|
import { type Contract3Bundle, type CredentialsFetcher, type TimerHost } from "./credentials.js";
|
|
14
16
|
export type MqttConnectionState = "idle" | "connecting" | "connected" | "reconnecting" | "closed";
|
|
17
|
+
/**
|
|
18
|
+
* A connection that drops before this grace window after `connect` is treated
|
|
19
|
+
* as a failed attempt: backoff counters are not reset (AWS IoT often accepts
|
|
20
|
+
* then closes immediately after a denied publish).
|
|
21
|
+
*/
|
|
22
|
+
export declare const CONNECT_STABLE_GRACE_MS = 5000;
|
|
23
|
+
/** Always emit the first N close info lines, then at most one per interval. */
|
|
24
|
+
export declare const CLOSE_LOG_ALWAYS_COUNT = 3;
|
|
25
|
+
export declare const CLOSE_LOG_INTERVAL_MS = 60000;
|
|
15
26
|
export interface PresencePayload {
|
|
16
27
|
v: 1;
|
|
17
28
|
status: "online" | "offline";
|
|
@@ -49,6 +60,8 @@ export interface PresenceClientOptions {
|
|
|
49
60
|
onOnline?: (companies: string[]) => void;
|
|
50
61
|
onState?: (state: MqttConnectionState) => void;
|
|
51
62
|
onError?: (err: unknown) => void;
|
|
63
|
+
/** Non-error info lines (e.g. rate-limited mqtt close / backoff). */
|
|
64
|
+
onInfo?: (message: string) => void;
|
|
52
65
|
/** Fired when refusal appears, code changes, clears, or nextRetryAt updates. */
|
|
53
66
|
onRefusal?: (refusal: PresenceRefusal | null) => void;
|
|
54
67
|
now?: () => Date;
|
|
@@ -78,6 +91,10 @@ export declare class PresenceClient {
|
|
|
78
91
|
private attempt;
|
|
79
92
|
private lastBackoffMs;
|
|
80
93
|
private reconnectHandle;
|
|
94
|
+
private stableHandle;
|
|
95
|
+
private connectedAtMs;
|
|
96
|
+
private closeLogCount;
|
|
97
|
+
private lastCloseLogAtMs;
|
|
81
98
|
private stopped;
|
|
82
99
|
private generation;
|
|
83
100
|
private publishedTopics;
|
|
@@ -118,7 +135,9 @@ export declare class PresenceClient {
|
|
|
118
135
|
/** Publish retained online to every own presence topic (connect / renew). */
|
|
119
136
|
private publishAll;
|
|
120
137
|
private scheduleReconnect;
|
|
138
|
+
private maybeLogClose;
|
|
121
139
|
private clearReconnect;
|
|
140
|
+
private clearStableTimer;
|
|
122
141
|
}
|
|
123
142
|
/** Production mqtt.connect wrapper (typed). */
|
|
124
143
|
export declare function defaultMqttConnect(url: string, opts: IClientOptions): MqttClient;
|
|
@@ -7,11 +7,22 @@
|
|
|
7
7
|
* - Offline is server-only (IoT lifecycle → PresenceIngestFunction)
|
|
8
8
|
* - Never subscribes to thread topics
|
|
9
9
|
* - Reconnects with monotonic full-jitter backoff 1s–60s on close / network
|
|
10
|
+
* - Backoff resets only after the connection stays up past
|
|
11
|
+
* {@link CONNECT_STABLE_GRACE_MS} (broker accept-then-close must not reset)
|
|
10
12
|
* - Server credential refusals use a long retry (default 10m ±20%)
|
|
11
13
|
*/
|
|
12
14
|
import mqtt from "mqtt";
|
|
13
15
|
import { CredentialVendError, CredentialRenewalManager, MQTT_KEEPALIVE_SECONDS, clampRetryDelayMs, defaultRefusedRetryMs, realTimerHost, refusedRetryDelayMs, scheduleBoundedTimeout, } from "./credentials.js";
|
|
14
16
|
import { presignIotWssUrl } from "./presign.js";
|
|
17
|
+
/**
|
|
18
|
+
* A connection that drops before this grace window after `connect` is treated
|
|
19
|
+
* as a failed attempt: backoff counters are not reset (AWS IoT often accepts
|
|
20
|
+
* then closes immediately after a denied publish).
|
|
21
|
+
*/
|
|
22
|
+
export const CONNECT_STABLE_GRACE_MS = 5_000;
|
|
23
|
+
/** Always emit the first N close info lines, then at most one per interval. */
|
|
24
|
+
export const CLOSE_LOG_ALWAYS_COUNT = 3;
|
|
25
|
+
export const CLOSE_LOG_INTERVAL_MS = 60_000;
|
|
15
26
|
/**
|
|
16
27
|
* Full-jitter capped exponential backoff (1s base → 60s cap by default),
|
|
17
28
|
* floored at `previousMs` so consecutive failures never shrink the delay.
|
|
@@ -50,6 +61,10 @@ export class PresenceClient {
|
|
|
50
61
|
attempt = 0;
|
|
51
62
|
lastBackoffMs = 0;
|
|
52
63
|
reconnectHandle = null;
|
|
64
|
+
stableHandle = null;
|
|
65
|
+
connectedAtMs = null;
|
|
66
|
+
closeLogCount = 0;
|
|
67
|
+
lastCloseLogAtMs = Number.NEGATIVE_INFINITY;
|
|
53
68
|
stopped = false;
|
|
54
69
|
generation = 0;
|
|
55
70
|
publishedTopics = [];
|
|
@@ -113,6 +128,8 @@ export class PresenceClient {
|
|
|
113
128
|
this.generation += 1;
|
|
114
129
|
this.renewal.stop();
|
|
115
130
|
this.clearReconnect();
|
|
131
|
+
this.clearStableTimer();
|
|
132
|
+
this.connectedAtMs = null;
|
|
116
133
|
this.teardownClient(false);
|
|
117
134
|
this.clearRefusal(/* logClear */ false);
|
|
118
135
|
this.setState("closed");
|
|
@@ -128,7 +145,7 @@ export class PresenceClient {
|
|
|
128
145
|
return;
|
|
129
146
|
}
|
|
130
147
|
}
|
|
131
|
-
// Backoff counters reset only
|
|
148
|
+
// Backoff counters reset only after a stable connection — not here.
|
|
132
149
|
this.clearReconnect();
|
|
133
150
|
void this.connectOnce();
|
|
134
151
|
}
|
|
@@ -155,7 +172,7 @@ export class PresenceClient {
|
|
|
155
172
|
this.clearRefusal(true);
|
|
156
173
|
if (this.stopped)
|
|
157
174
|
return;
|
|
158
|
-
// Reconnect with the new presigned URL; backoff resets only
|
|
175
|
+
// Reconnect with the new presigned URL; backoff resets only after stable connect.
|
|
159
176
|
await this.connectOnce();
|
|
160
177
|
}
|
|
161
178
|
handleRenewalError(err, info) {
|
|
@@ -200,6 +217,8 @@ export class PresenceClient {
|
|
|
200
217
|
if (this.stopped)
|
|
201
218
|
return;
|
|
202
219
|
this.clearReconnect();
|
|
220
|
+
this.clearStableTimer();
|
|
221
|
+
this.connectedAtMs = null;
|
|
203
222
|
const generation = ++this.generation;
|
|
204
223
|
this.teardownClient(true);
|
|
205
224
|
try {
|
|
@@ -233,8 +252,17 @@ export class PresenceClient {
|
|
|
233
252
|
client.on("connect", () => {
|
|
234
253
|
if (this.stopped || generation !== this.generation)
|
|
235
254
|
return;
|
|
236
|
-
|
|
237
|
-
|
|
255
|
+
// Do not reset attempt here — broker may accept then close immediately
|
|
256
|
+
// (denied publish / policy). Reset only after CONNECT_STABLE_GRACE_MS.
|
|
257
|
+
this.connectedAtMs = this.timers.now();
|
|
258
|
+
this.clearStableTimer();
|
|
259
|
+
this.stableHandle = scheduleBoundedTimeout(this.timers, () => {
|
|
260
|
+
this.stableHandle = null;
|
|
261
|
+
if (this.stopped || generation !== this.generation)
|
|
262
|
+
return;
|
|
263
|
+
this.attempt = 0;
|
|
264
|
+
this.lastBackoffMs = 0;
|
|
265
|
+
}, CONNECT_STABLE_GRACE_MS);
|
|
238
266
|
this.setState("connected");
|
|
239
267
|
void this.publishAll("online").then(() => {
|
|
240
268
|
this.options.onOnline?.(bundle.companies.map((c) => c.companyUid));
|
|
@@ -248,7 +276,13 @@ export class PresenceClient {
|
|
|
248
276
|
client.on("close", () => {
|
|
249
277
|
if (this.stopped || generation !== this.generation)
|
|
250
278
|
return;
|
|
251
|
-
this.
|
|
279
|
+
const elapsedMs = this.connectedAtMs != null
|
|
280
|
+
? Math.max(0, this.timers.now() - this.connectedAtMs)
|
|
281
|
+
: 0;
|
|
282
|
+
this.connectedAtMs = null;
|
|
283
|
+
this.clearStableTimer();
|
|
284
|
+
const delay = this.scheduleReconnect();
|
|
285
|
+
this.maybeLogClose(elapsedMs, delay);
|
|
252
286
|
});
|
|
253
287
|
}
|
|
254
288
|
catch (err) {
|
|
@@ -295,7 +329,7 @@ export class PresenceClient {
|
|
|
295
329
|
}
|
|
296
330
|
scheduleReconnect(opts) {
|
|
297
331
|
if (this.stopped)
|
|
298
|
-
return;
|
|
332
|
+
return 0;
|
|
299
333
|
this.setState("reconnecting");
|
|
300
334
|
this.clearReconnect();
|
|
301
335
|
let delay;
|
|
@@ -326,6 +360,17 @@ export class PresenceClient {
|
|
|
326
360
|
}
|
|
327
361
|
void this.connectOnce();
|
|
328
362
|
}, delay);
|
|
363
|
+
return delay;
|
|
364
|
+
}
|
|
365
|
+
maybeLogClose(elapsedMs, delayMs) {
|
|
366
|
+
const now = this.timers.now();
|
|
367
|
+
const withinAlways = this.closeLogCount < CLOSE_LOG_ALWAYS_COUNT;
|
|
368
|
+
const intervalElapsed = now - this.lastCloseLogAtMs >= CLOSE_LOG_INTERVAL_MS;
|
|
369
|
+
if (!withinAlways && !intervalElapsed)
|
|
370
|
+
return;
|
|
371
|
+
this.closeLogCount += 1;
|
|
372
|
+
this.lastCloseLogAtMs = now;
|
|
373
|
+
this.options.onInfo?.(`presence mqtt closed after ${elapsedMs}ms; reconnect in ${delayMs}ms`);
|
|
329
374
|
}
|
|
330
375
|
clearReconnect() {
|
|
331
376
|
if (this.reconnectHandle !== null) {
|
|
@@ -333,6 +378,12 @@ export class PresenceClient {
|
|
|
333
378
|
this.reconnectHandle = null;
|
|
334
379
|
}
|
|
335
380
|
}
|
|
381
|
+
clearStableTimer() {
|
|
382
|
+
if (this.stableHandle !== null) {
|
|
383
|
+
this.stableHandle.clear();
|
|
384
|
+
this.stableHandle = null;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
336
387
|
}
|
|
337
388
|
/** Production mqtt.connect wrapper (typed). */
|
|
338
389
|
export function defaultMqttConnect(url, opts) {
|
|
@@ -64,17 +64,18 @@ export async function runMeshDaemon(deps = {}) {
|
|
|
64
64
|
}
|
|
65
65
|
writeDaemonState(dir, defaultDaemonState(lockDeps.pid, now));
|
|
66
66
|
log(dir, `daemon started pid=${lockDeps.pid}`);
|
|
67
|
-
let token;
|
|
68
67
|
// Opt into machine-credential minting when the box has creds (systemd exports
|
|
69
68
|
// HQ_MACHINE_CREDS_FILE). On a person laptop with no machine creds this falls
|
|
70
69
|
// through to the person login cache inside ensureCognitoToken.
|
|
70
|
+
//
|
|
71
|
+
// Resolve the token on EVERY use. ensureCognitoToken reads the on-disk cache
|
|
72
|
+
// and refreshes/mints when the token is near expiry, so this is cheap; a
|
|
73
|
+
// process-lifetime memo (the previous behaviour) handed a Cognito token that
|
|
74
|
+
// expires after ~1h to every vend/flush forever, so the second credential
|
|
75
|
+
// renewal (~96 min in) and everything after it failed with HTTP 401 and the
|
|
76
|
+
// daemon went dark once its IoT credentials expired.
|
|
71
77
|
const defaultGetToken = async () => ensureCognitoToken({ interactive: false, tokenSource: "machine" });
|
|
72
|
-
const getToken = deps.getToken ??
|
|
73
|
-
(async () => {
|
|
74
|
-
if (!token)
|
|
75
|
-
token = await defaultGetToken();
|
|
76
|
-
return token;
|
|
77
|
-
});
|
|
78
|
+
const getToken = deps.getToken ?? defaultGetToken;
|
|
78
79
|
const flushFn = deps.flush ??
|
|
79
80
|
(async () => {
|
|
80
81
|
const t = await getToken();
|
|
@@ -152,6 +153,9 @@ export async function runMeshDaemon(deps = {}) {
|
|
|
152
153
|
patchDaemonState(dir, { lastErrorCode: msg.slice(0, 120) }, now);
|
|
153
154
|
log(dir, `presence error: ${msg.slice(0, 200)}`);
|
|
154
155
|
},
|
|
156
|
+
onInfo: (message) => {
|
|
157
|
+
log(dir, message.slice(0, 200));
|
|
158
|
+
},
|
|
155
159
|
};
|
|
156
160
|
presence = new PresenceClient(presenceOpts);
|
|
157
161
|
try {
|
package/dist/main.js
CHANGED
|
@@ -8,60 +8,6 @@ import "./node-preflight.js";
|
|
|
8
8
|
import "./node-network-compat.js";
|
|
9
9
|
import { Command } from "commander";
|
|
10
10
|
import { initSentry, Sentry } from "./sentry.js";
|
|
11
|
-
import { registerAddCommand } from "./commands/add.js";
|
|
12
|
-
import { registerSyncCommand } from "./commands/sync.js";
|
|
13
|
-
import { registerListCommand } from "./commands/list.js";
|
|
14
|
-
import { registerUpdateCommand } from "./commands/update.js";
|
|
15
|
-
import { registerCloudCommands } from "./commands/cloud.js";
|
|
16
|
-
import { registerSyncModeCommand } from "./commands/sync-mode.js";
|
|
17
|
-
import { registerSyncNarrowCommand } from "./commands/sync-narrow.js";
|
|
18
|
-
import { registerCloudProvisionCommands } from "./commands/cloud-provision.js";
|
|
19
|
-
import { registerCloudDemoteCommands } from "./commands/cloud-demote.js";
|
|
20
|
-
import { registerLoginCommand } from "./commands/login.js";
|
|
21
|
-
import { registerLogoutCommand } from "./commands/logout.js";
|
|
22
|
-
import { registerWhoamiCommand } from "./commands/whoami.js";
|
|
23
|
-
import { registerOnboardCommand } from "./commands/onboard.js";
|
|
24
|
-
import { registerPackageInstallCommand } from "./commands/pkg-install.js";
|
|
25
|
-
import { registerPackageRemoveCommand } from "./commands/pkg-remove.js";
|
|
26
|
-
import { registerPackageUpdateCommand } from "./commands/pkg-update.js";
|
|
27
|
-
import { registerPackageListCommand } from "./commands/pkg-list.js";
|
|
28
|
-
import { registerPacksCommand } from "./commands/packs.js";
|
|
29
|
-
import { registerPublishCommand } from "./commands/publish.js";
|
|
30
|
-
import { registerCreatorsCommand } from "./commands/creators.js";
|
|
31
|
-
import { registerTeamSyncCommand } from "./commands/team-sync.js";
|
|
32
|
-
import { registerAuthCommands } from "./commands/auth.js";
|
|
33
|
-
import { registerApiKeysCommand } from "./commands/api-keys.js";
|
|
34
|
-
import { registerSecretsCommand } from "./commands/secrets.js";
|
|
35
|
-
import { registerRunCommand } from "./commands/run.js";
|
|
36
|
-
import { registerGroupsCommand } from "./commands/groups.js";
|
|
37
|
-
import { registerWorkersCommand } from "./commands/workers.js";
|
|
38
|
-
import { registerGroupGrantsCommand } from "./commands/group-grants.js";
|
|
39
|
-
import { registerFilesCommand } from "./commands/files.js";
|
|
40
|
-
import { registerFilesBrowseCommands } from "./commands/files-browse.js";
|
|
41
|
-
import { registerSkillCommand } from "./commands/skill.js";
|
|
42
|
-
import { registerMembersCommand } from "./commands/members.js";
|
|
43
|
-
import { registerPeopleCommand } from "./commands/people.js";
|
|
44
|
-
import { registerDmCommand } from "./commands/dm.js";
|
|
45
|
-
import { registerChannelsCommand } from "./commands/channels.js";
|
|
46
|
-
import { registerFeedbackCommand } from "./commands/feedback.js";
|
|
47
|
-
import { registerMeetingsCommand } from "./commands/meetings.js";
|
|
48
|
-
import { registerSourcesCommand } from "./commands/sources.js";
|
|
49
|
-
import { registerSignalsCommand } from "./commands/signals.js";
|
|
50
|
-
import { registerIntegrationsCommand } from "./commands/integrations.js";
|
|
51
|
-
import { registerReindexCommand } from "./commands/reindex.js";
|
|
52
|
-
import { registerRescueCommand } from "./commands/rescue.js";
|
|
53
|
-
import { registerMcpCommand } from "./commands/mcp-status.js";
|
|
54
|
-
import { registerCrmCommand } from "./commands/crm.js";
|
|
55
|
-
import { registerCompanyCommand } from "./commands/company.js";
|
|
56
|
-
import { registerAgentsCommand } from "./commands/agents.js";
|
|
57
|
-
import { registerOutpostsCommand } from "./commands/outposts.js";
|
|
58
|
-
import { registerBillingCommand } from "./commands/billing.js";
|
|
59
|
-
import { registerDbCommand } from "./commands/db.js";
|
|
60
|
-
import { registerCoreCommands } from "./commands/core.js";
|
|
61
|
-
import { registerSearchCommand } from "./commands/search.js";
|
|
62
|
-
import { registerIndexCommand } from "./commands/index-cmd.js";
|
|
63
|
-
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
64
|
-
import { registerMeshCommand } from "./commands/mesh.js";
|
|
65
11
|
import { sanitizeArgv } from "./utils/feedback-diagnostics.js";
|
|
66
12
|
import { environmentalFsErrorMessage } from "./utils/environmental-error.js";
|
|
67
13
|
import { syncStateLockMessage } from "./utils/sync-state-lock-error.js";
|
|
@@ -92,6 +38,7 @@ import { refreshVersionCache, staleAgainstCachedLatest, } from "./utils/version-
|
|
|
92
38
|
import { enforceVersionGate, shouldSkipGate, } from "./utils/version-gate.js";
|
|
93
39
|
import { autoUpdateAndReexec } from "./utils/self-update.js";
|
|
94
40
|
import { CLI_VERSION } from "./cli-version.js";
|
|
41
|
+
import { findLazyCommand } from "./lazy-commands.js";
|
|
95
42
|
import { emitCliSessionStarted } from "./utils/cli-telemetry.js";
|
|
96
43
|
import { reportCliClientHealthInvocation } from "./utils/client-health.js";
|
|
97
44
|
import { settleWithin } from "./utils/settle-with-timeout.js";
|
|
@@ -148,151 +95,6 @@ program
|
|
|
148
95
|
.name("hq")
|
|
149
96
|
.description("HQ management CLI — modules, packages, and cloud sync")
|
|
150
97
|
.version(CLI_VERSION);
|
|
151
|
-
// Module management subcommand group
|
|
152
|
-
const modulesCmd = program
|
|
153
|
-
.command("modules")
|
|
154
|
-
.description("Module management commands");
|
|
155
|
-
registerAddCommand(modulesCmd);
|
|
156
|
-
registerSyncCommand(modulesCmd);
|
|
157
|
-
registerListCommand(modulesCmd);
|
|
158
|
-
registerUpdateCommand(modulesCmd);
|
|
159
|
-
// Package management subcommand group
|
|
160
|
-
const packagesCmd = program
|
|
161
|
-
.command("packages")
|
|
162
|
-
.description("Package management commands");
|
|
163
|
-
registerPackageInstallCommand(packagesCmd);
|
|
164
|
-
registerPackageRemoveCommand(packagesCmd);
|
|
165
|
-
registerPackageUpdateCommand(packagesCmd);
|
|
166
|
-
registerPackageListCommand(packagesCmd);
|
|
167
|
-
// Content-pack lifecycle (core/packages/hq-pack-*). Distinct from the registry
|
|
168
|
-
// `packages` system above. Available as both `hq packages packs …` (grouped)
|
|
169
|
-
// and `hq packs …` (top-level convenience).
|
|
170
|
-
registerPacksCommand(packagesCmd);
|
|
171
|
-
registerPacksCommand(program);
|
|
172
|
-
// Top-level shortcuts for package commands
|
|
173
|
-
// "hq install <slug>" = "hq packages install <slug>"
|
|
174
|
-
// "hq remove <slug>" = "hq packages remove <slug>"
|
|
175
|
-
registerPackageInstallCommand(program);
|
|
176
|
-
registerPackageRemoveCommand(program);
|
|
177
|
-
// Marketplace publish (top-level — packer + authenticated upload, US-004)
|
|
178
|
-
// "hq publish <skill-or-worker-path>" packages and submits a pack to the
|
|
179
|
-
// marketplace via POST /v1/listings.
|
|
180
|
-
registerPublishCommand(program);
|
|
181
|
-
// `hq creators apply` — request verified-creator access (required to publish).
|
|
182
|
-
registerCreatorsCommand(program);
|
|
183
|
-
// Cloud sync subcommand group
|
|
184
|
-
const syncCmd = program
|
|
185
|
-
.command("sync")
|
|
186
|
-
.description("Cloud sync commands — sync HQ to S3 for mobile access");
|
|
187
|
-
registerCloudCommands(syncCmd);
|
|
188
|
-
registerSyncModeCommand(syncCmd);
|
|
189
|
-
registerSyncNarrowCommand(syncCmd);
|
|
190
|
-
// Cloud provisioning subcommand group (entity + bucket + initial sync)
|
|
191
|
-
// Distinct from `hq sync` which assumes provisioning has already happened.
|
|
192
|
-
const cloudCmd = program
|
|
193
|
-
.command("cloud")
|
|
194
|
-
.description("Cloud commands — provision entities and manage cloud-backed companies");
|
|
195
|
-
registerCloudProvisionCommands(cloudCmd);
|
|
196
|
-
registerCloudDemoteCommands(cloudCmd);
|
|
197
|
-
// Team commands (top-level)
|
|
198
|
-
registerTeamSyncCommand(program);
|
|
199
|
-
// Auth commands (top-level — Cognito OAuth)
|
|
200
|
-
registerLoginCommand(program);
|
|
201
|
-
registerLogoutCommand(program);
|
|
202
|
-
registerWhoamiCommand(program);
|
|
203
|
-
registerAuthCommands(program);
|
|
204
|
-
// Secrets management (subcommand group — hq secrets set|get|list|delete|exec|generate-link|cache)
|
|
205
|
-
registerSecretsCommand(program);
|
|
206
|
-
// Vault databases (subcommand group — hq db status|sql|migrate|provision)
|
|
207
|
-
registerDbCommand(program);
|
|
208
|
-
// API key management (subcommand group — hq api-keys create|list|revoke)
|
|
209
|
-
registerApiKeysCommand(program);
|
|
210
|
-
// Schema-driven dev runner — hq run [options] -- <cmd>
|
|
211
|
-
registerRunCommand(program);
|
|
212
|
-
// Groups management (subcommand group — hq groups create|delete|add|remove|list|members)
|
|
213
|
-
registerGroupsCommand(program);
|
|
214
|
-
// Worker discovery + sharing (subcommand group — hq workers list|share)
|
|
215
|
-
registerWorkersCommand(program);
|
|
216
|
-
// Cross-company group grants (subcommand group —
|
|
217
|
-
// hq group-grants grant|revoke|outbound|inbound)
|
|
218
|
-
registerGroupGrantsCommand(program);
|
|
219
|
-
// Files ACL management (subcommand group — hq files share|unshare|acl)
|
|
220
|
-
// `registerFilesCommand` returns the `files` group so we can attach the
|
|
221
|
-
// browse-vs-sync subcommands (`hq files browse`/`cat`) onto the same group.
|
|
222
|
-
const filesCmd = registerFilesCommand(program);
|
|
223
|
-
registerFilesBrowseCommands(filesCmd);
|
|
224
|
-
// Comment-only skill improvement loop. Structured suggestion/review commands are
|
|
225
|
-
// intentionally absent; live content changes remain governed by FILE_ACL sync.
|
|
226
|
-
registerSkillCommand(program);
|
|
227
|
-
// Membership management (subcommand group — hq members invite|list|revoke)
|
|
228
|
-
registerMembersCommand(program);
|
|
229
|
-
// People directory (subcommand group — hq people list|search|resolve), reading
|
|
230
|
-
// the local companies/<co>/people store scoped to one company.
|
|
231
|
-
registerPeopleCommand(program);
|
|
232
|
-
registerDmCommand(program);
|
|
233
|
-
registerChannelsCommand(program);
|
|
234
|
-
// Onboarding (top-level — Cognito + vault-service provisioning)
|
|
235
|
-
registerOnboardCommand(program);
|
|
236
|
-
// Feedback (subcommand group — hq feedback bug|feature)
|
|
237
|
-
registerFeedbackCommand(program);
|
|
238
|
-
// Meetings (subcommand group — hq meetings list|get|search|transcript|notes)
|
|
239
|
-
registerMeetingsCommand(program);
|
|
240
|
-
// Sources read surface (subcommand group — hq sources list|get|channels|entities)
|
|
241
|
-
registerSourcesCommand(program);
|
|
242
|
-
// Signals read surface (subcommand group — hq signals list|get|types|entities)
|
|
243
|
-
registerSignalsCommand(program);
|
|
244
|
-
// Company-connected apps via the governed integration gateway
|
|
245
|
-
// (subcommand group — hq integrations list|tools|call|approve|reject)
|
|
246
|
-
registerIntegrationsCommand(program);
|
|
247
|
-
// Skill/personal-overlay mirroring + workers-registry regen. Invoked by the
|
|
248
|
-
// hq-core reindex hook shim (Stop / PostToolUse) and by sync()/rescue() after
|
|
249
|
-
// they change on-disk sources. Keeps a `master-sync` alias for one release.
|
|
250
|
-
// Implementation lives in @indigoai-us/hq-cloud.
|
|
251
|
-
registerReindexCommand(program);
|
|
252
|
-
// Drift-preserving HQ-core re-sync (top-level — `hq rescue`). CLI sibling of
|
|
253
|
-
// the HQ Sync app's "Update / Restore" pill; drives the same replace-rescue.sh
|
|
254
|
-
// shipped from @indigoai-us/hq-cloud.
|
|
255
|
-
registerRescueCommand(program);
|
|
256
|
-
// MCP pack observability (subcommand group — `hq mcp status`). Read-only
|
|
257
|
-
// provenance-based status across BOTH Claude + Codex runtimes (reads `_hqPack`
|
|
258
|
-
// off the configs, NOT linkStatus), with secret-redacted output + `--json`.
|
|
259
|
-
registerMcpCommand(program);
|
|
260
|
-
// Native CRM entity upsert (subcommand group — `hq crm entity upsert`). Wraps
|
|
261
|
-
// POST /crm/entities (the ontology write gate) so an authenticated company
|
|
262
|
-
// member can create/update canonical CRM entities in the company vault.
|
|
263
|
-
registerCrmCommand(program);
|
|
264
|
-
// Company settings (subcommand group — `hq company settings set`). Owner-only
|
|
265
|
-
// toggles for crmEnabled / ontologyEnabled via PUT /company-settings.
|
|
266
|
-
registerCompanyCommand(program);
|
|
267
|
-
// Cloud agent management (subcommand group — `hq agents …`). Rename, reconfigure,
|
|
268
|
-
// start/stop, and tear down a company's fleet agents via the hq-pro /v1/agents
|
|
269
|
-
// control plane — the same routes the web console's agents panel calls.
|
|
270
|
-
registerAgentsCommand(program);
|
|
271
|
-
// Personal Outpost management (subcommand group — `hq outposts …`). List, inspect,
|
|
272
|
-
// enable Codex on, refresh login for, and destroy your EC2 boxes via the hq-pro
|
|
273
|
-
// /outpost/* control plane.
|
|
274
|
-
registerOutpostsCommand(program);
|
|
275
|
-
// Billing (subcommand group — `hq billing …`). Check subscription/card state and
|
|
276
|
-
// mint a shareable Stripe card-capture link — the client side of the paid-
|
|
277
|
-
// provisioning gate for agents & Outposts.
|
|
278
|
-
registerBillingCommand(program);
|
|
279
|
-
// HQ scaffold scripts hosted by the CLI (hidden group — `hq core …`). Not a
|
|
280
|
-
// public surface: every entry is invoked by an HQ skill, hook, or forwarder, and
|
|
281
|
-
// the source-root entries are maintainer tools that must never touch a live
|
|
282
|
-
// install. Registered from a manifest in the module, not wired per script here.
|
|
283
|
-
registerCoreCommands(program);
|
|
284
|
-
// Local qmd search and index management. Kept distinct from `hq reindex`,
|
|
285
|
-
// which converges scaffold-owned files and hooks rather than search data.
|
|
286
|
-
registerSearchCommand(program);
|
|
287
|
-
registerIndexCommand(program);
|
|
288
|
-
// Hook guardrail diagnostics (top-level — `hq doctor`). Read-only, offline
|
|
289
|
-
// verification that HQ's hooks are wired and firing, backed by an extensible
|
|
290
|
-
// check registry so later check families (vault, sync, MCP, …) plug in without
|
|
291
|
-
// engine changes.
|
|
292
|
-
registerDoctorCommand(program);
|
|
293
|
-
// Work mesh (subcommand group — `hq mesh …`). Native REST + cache. Distinct
|
|
294
|
-
// from `hq doctor` (hook guardrails). Does not start MQTT listen.
|
|
295
|
-
registerMeshCommand(program);
|
|
296
98
|
program.hook("preAction", async () => {
|
|
297
99
|
// Both are best-effort and fully swallowed: neither can change the command's
|
|
298
100
|
// result or exit code. The 1.2s bound they carry is a TIMER, so it only
|
|
@@ -351,6 +153,19 @@ export async function runCli() {
|
|
|
351
153
|
}
|
|
352
154
|
}
|
|
353
155
|
}
|
|
156
|
+
// Register only what this invocation needs. A hot command named in the
|
|
157
|
+
// lazy manifest imports its own module and nothing else; everything else —
|
|
158
|
+
// `--help`, a bare `hq`, an unknown command, any command not on the
|
|
159
|
+
// manifest — falls back to the complete graph, so its behaviour is
|
|
160
|
+
// unchanged. See register-all.ts for the measurements that motivated this.
|
|
161
|
+
const lazy = findLazyCommand(process.argv);
|
|
162
|
+
if (lazy) {
|
|
163
|
+
await lazy.register(program);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const { registerAllCommands } = await import("./register-all.js");
|
|
167
|
+
registerAllCommands(program);
|
|
168
|
+
}
|
|
354
169
|
await program.parseAsync();
|
|
355
170
|
}
|
|
356
171
|
catch (err) {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The full hq command graph — every `register*Command` call, moved here verbatim
|
|
3
|
+
* from main.ts.
|
|
4
|
+
*
|
|
5
|
+
* WHY IT IS ITS OWN MODULE: these 54 imports pull ~60 command modules and their
|
|
6
|
+
* dependency subtrees, and main.ts used to load all of them at module scope. On
|
|
7
|
+
* an outpost that cost real CPU, because the agent fleet calls `hq secrets`
|
|
8
|
+
* about 39 times a minute and each invocation paid for the entire graph before
|
|
9
|
+
* running one command. Measured on Outpost 2 (i-09424eff61920a4ac), CPU-seconds
|
|
10
|
+
* per process:
|
|
11
|
+
*
|
|
12
|
+
* node -e "" 0.03
|
|
13
|
+
* dist/commands/secrets.js 1.13 <- what `hq secrets` actually needs
|
|
14
|
+
* dist/main.js (full graph) 1.88 <- what it used to pay
|
|
15
|
+
*
|
|
16
|
+
* So ~0.75 CPU-seconds of every `hq secrets` was spent importing commands it
|
|
17
|
+
* never ran. At 39 invocations/minute that is ~0.5 of a core, continuously.
|
|
18
|
+
*
|
|
19
|
+
* Splitting the graph out lets the entrypoint import ONE command module for the
|
|
20
|
+
* hot paths named in lazy-commands.ts, and fall back to this module — the
|
|
21
|
+
* complete, unchanged registration — for everything else: `--help`, a bare
|
|
22
|
+
* `hq`, an unknown command, and every command not in that manifest. Anything
|
|
23
|
+
* not on the manifest therefore behaves exactly as before.
|
|
24
|
+
*
|
|
25
|
+
* Keep this list and lazy-commands.ts in sync through the parity test in
|
|
26
|
+
* lazy-commands.test.ts, which registers both ways and compares the resulting
|
|
27
|
+
* command shapes. Same discipline as commands/scaffold-fast.ts and core.ts.
|
|
28
|
+
*/
|
|
29
|
+
import type { Command } from "commander";
|
|
30
|
+
/** Register the complete hq command graph onto `program`. */
|
|
31
|
+
export declare function registerAllCommands(program: Command): void;
|
|
32
|
+
//# sourceMappingURL=register-all.d.ts.map
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The full hq command graph — every `register*Command` call, moved here verbatim
|
|
3
|
+
* from main.ts.
|
|
4
|
+
*
|
|
5
|
+
* WHY IT IS ITS OWN MODULE: these 54 imports pull ~60 command modules and their
|
|
6
|
+
* dependency subtrees, and main.ts used to load all of them at module scope. On
|
|
7
|
+
* an outpost that cost real CPU, because the agent fleet calls `hq secrets`
|
|
8
|
+
* about 39 times a minute and each invocation paid for the entire graph before
|
|
9
|
+
* running one command. Measured on Outpost 2 (i-09424eff61920a4ac), CPU-seconds
|
|
10
|
+
* per process:
|
|
11
|
+
*
|
|
12
|
+
* node -e "" 0.03
|
|
13
|
+
* dist/commands/secrets.js 1.13 <- what `hq secrets` actually needs
|
|
14
|
+
* dist/main.js (full graph) 1.88 <- what it used to pay
|
|
15
|
+
*
|
|
16
|
+
* So ~0.75 CPU-seconds of every `hq secrets` was spent importing commands it
|
|
17
|
+
* never ran. At 39 invocations/minute that is ~0.5 of a core, continuously.
|
|
18
|
+
*
|
|
19
|
+
* Splitting the graph out lets the entrypoint import ONE command module for the
|
|
20
|
+
* hot paths named in lazy-commands.ts, and fall back to this module — the
|
|
21
|
+
* complete, unchanged registration — for everything else: `--help`, a bare
|
|
22
|
+
* `hq`, an unknown command, and every command not in that manifest. Anything
|
|
23
|
+
* not on the manifest therefore behaves exactly as before.
|
|
24
|
+
*
|
|
25
|
+
* Keep this list and lazy-commands.ts in sync through the parity test in
|
|
26
|
+
* lazy-commands.test.ts, which registers both ways and compares the resulting
|
|
27
|
+
* command shapes. Same discipline as commands/scaffold-fast.ts and core.ts.
|
|
28
|
+
*/
|
|
29
|
+
import { registerAddCommand } from "./commands/add.js";
|
|
30
|
+
import { registerSyncCommand } from "./commands/sync.js";
|
|
31
|
+
import { registerListCommand } from "./commands/list.js";
|
|
32
|
+
import { registerUpdateCommand } from "./commands/update.js";
|
|
33
|
+
import { registerCloudCommands } from "./commands/cloud.js";
|
|
34
|
+
import { registerSyncModeCommand } from "./commands/sync-mode.js";
|
|
35
|
+
import { registerSyncNarrowCommand } from "./commands/sync-narrow.js";
|
|
36
|
+
import { registerCloudProvisionCommands } from "./commands/cloud-provision.js";
|
|
37
|
+
import { registerCloudDemoteCommands } from "./commands/cloud-demote.js";
|
|
38
|
+
import { registerLoginCommand } from "./commands/login.js";
|
|
39
|
+
import { registerLogoutCommand } from "./commands/logout.js";
|
|
40
|
+
import { registerWhoamiCommand } from "./commands/whoami.js";
|
|
41
|
+
import { registerOnboardCommand } from "./commands/onboard.js";
|
|
42
|
+
import { registerPackageInstallCommand } from "./commands/pkg-install.js";
|
|
43
|
+
import { registerPackageRemoveCommand } from "./commands/pkg-remove.js";
|
|
44
|
+
import { registerPackageUpdateCommand } from "./commands/pkg-update.js";
|
|
45
|
+
import { registerPackageListCommand } from "./commands/pkg-list.js";
|
|
46
|
+
import { registerPacksCommand } from "./commands/packs.js";
|
|
47
|
+
import { registerPublishCommand } from "./commands/publish.js";
|
|
48
|
+
import { registerCreatorsCommand } from "./commands/creators.js";
|
|
49
|
+
import { registerTeamSyncCommand } from "./commands/team-sync.js";
|
|
50
|
+
import { registerAuthCommands } from "./commands/auth.js";
|
|
51
|
+
import { registerApiKeysCommand } from "./commands/api-keys.js";
|
|
52
|
+
import { registerSecretsCommand } from "./commands/secrets.js";
|
|
53
|
+
import { registerRunCommand } from "./commands/run.js";
|
|
54
|
+
import { registerGroupsCommand } from "./commands/groups.js";
|
|
55
|
+
import { registerWorkersCommand } from "./commands/workers.js";
|
|
56
|
+
import { registerGroupGrantsCommand } from "./commands/group-grants.js";
|
|
57
|
+
import { registerFilesCommand } from "./commands/files.js";
|
|
58
|
+
import { registerFilesBrowseCommands } from "./commands/files-browse.js";
|
|
59
|
+
import { registerSkillCommand } from "./commands/skill.js";
|
|
60
|
+
import { registerMembersCommand } from "./commands/members.js";
|
|
61
|
+
import { registerPeopleCommand } from "./commands/people.js";
|
|
62
|
+
import { registerDmCommand } from "./commands/dm.js";
|
|
63
|
+
import { registerChannelsCommand } from "./commands/channels.js";
|
|
64
|
+
import { registerFeedbackCommand } from "./commands/feedback.js";
|
|
65
|
+
import { registerMeetingsCommand } from "./commands/meetings.js";
|
|
66
|
+
import { registerSourcesCommand } from "./commands/sources.js";
|
|
67
|
+
import { registerSignalsCommand } from "./commands/signals.js";
|
|
68
|
+
import { registerIntegrationsCommand } from "./commands/integrations.js";
|
|
69
|
+
import { registerReindexCommand } from "./commands/reindex.js";
|
|
70
|
+
import { registerRescueCommand } from "./commands/rescue.js";
|
|
71
|
+
import { registerMcpCommand } from "./commands/mcp-status.js";
|
|
72
|
+
import { registerCrmCommand } from "./commands/crm.js";
|
|
73
|
+
import { registerCompanyCommand } from "./commands/company.js";
|
|
74
|
+
import { registerAgentsCommand } from "./commands/agents.js";
|
|
75
|
+
import { registerOutpostsCommand } from "./commands/outposts.js";
|
|
76
|
+
import { registerBillingCommand } from "./commands/billing.js";
|
|
77
|
+
import { registerDbCommand } from "./commands/db.js";
|
|
78
|
+
import { registerCoreCommands } from "./commands/core.js";
|
|
79
|
+
import { registerSearchCommand } from "./commands/search.js";
|
|
80
|
+
import { registerIndexCommand } from "./commands/index-cmd.js";
|
|
81
|
+
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
82
|
+
import { registerMeshCommand } from "./commands/mesh.js";
|
|
83
|
+
/** Register the complete hq command graph onto `program`. */
|
|
84
|
+
export function registerAllCommands(program) {
|
|
85
|
+
// Module management subcommand group
|
|
86
|
+
const modulesCmd = program
|
|
87
|
+
.command("modules")
|
|
88
|
+
.description("Module management commands");
|
|
89
|
+
registerAddCommand(modulesCmd);
|
|
90
|
+
registerSyncCommand(modulesCmd);
|
|
91
|
+
registerListCommand(modulesCmd);
|
|
92
|
+
registerUpdateCommand(modulesCmd);
|
|
93
|
+
// Package management subcommand group
|
|
94
|
+
const packagesCmd = program
|
|
95
|
+
.command("packages")
|
|
96
|
+
.description("Package management commands");
|
|
97
|
+
registerPackageInstallCommand(packagesCmd);
|
|
98
|
+
registerPackageRemoveCommand(packagesCmd);
|
|
99
|
+
registerPackageUpdateCommand(packagesCmd);
|
|
100
|
+
registerPackageListCommand(packagesCmd);
|
|
101
|
+
// Content-pack lifecycle (core/packages/hq-pack-*). Distinct from the registry
|
|
102
|
+
// `packages` system above. Available as both `hq packages packs …` (grouped)
|
|
103
|
+
// and `hq packs …` (top-level convenience).
|
|
104
|
+
registerPacksCommand(packagesCmd);
|
|
105
|
+
registerPacksCommand(program);
|
|
106
|
+
// Top-level shortcuts for package commands
|
|
107
|
+
// "hq install <slug>" = "hq packages install <slug>"
|
|
108
|
+
// "hq remove <slug>" = "hq packages remove <slug>"
|
|
109
|
+
registerPackageInstallCommand(program);
|
|
110
|
+
registerPackageRemoveCommand(program);
|
|
111
|
+
// Marketplace publish (top-level — packer + authenticated upload, US-004)
|
|
112
|
+
// "hq publish <skill-or-worker-path>" packages and submits a pack to the
|
|
113
|
+
// marketplace via POST /v1/listings.
|
|
114
|
+
registerPublishCommand(program);
|
|
115
|
+
// `hq creators apply` — request verified-creator access (required to publish).
|
|
116
|
+
registerCreatorsCommand(program);
|
|
117
|
+
// Cloud sync subcommand group
|
|
118
|
+
const syncCmd = program
|
|
119
|
+
.command("sync")
|
|
120
|
+
.description("Cloud sync commands — sync HQ to S3 for mobile access");
|
|
121
|
+
registerCloudCommands(syncCmd);
|
|
122
|
+
registerSyncModeCommand(syncCmd);
|
|
123
|
+
registerSyncNarrowCommand(syncCmd);
|
|
124
|
+
// Cloud provisioning subcommand group (entity + bucket + initial sync)
|
|
125
|
+
// Distinct from `hq sync` which assumes provisioning has already happened.
|
|
126
|
+
const cloudCmd = program
|
|
127
|
+
.command("cloud")
|
|
128
|
+
.description("Cloud commands — provision entities and manage cloud-backed companies");
|
|
129
|
+
registerCloudProvisionCommands(cloudCmd);
|
|
130
|
+
registerCloudDemoteCommands(cloudCmd);
|
|
131
|
+
// Team commands (top-level)
|
|
132
|
+
registerTeamSyncCommand(program);
|
|
133
|
+
// Auth commands (top-level — Cognito OAuth)
|
|
134
|
+
registerLoginCommand(program);
|
|
135
|
+
registerLogoutCommand(program);
|
|
136
|
+
registerWhoamiCommand(program);
|
|
137
|
+
registerAuthCommands(program);
|
|
138
|
+
// Secrets management (subcommand group — hq secrets set|get|list|delete|exec|generate-link|cache)
|
|
139
|
+
registerSecretsCommand(program);
|
|
140
|
+
// Vault databases (subcommand group — hq db status|sql|migrate|provision)
|
|
141
|
+
registerDbCommand(program);
|
|
142
|
+
// API key management (subcommand group — hq api-keys create|list|revoke)
|
|
143
|
+
registerApiKeysCommand(program);
|
|
144
|
+
// Schema-driven dev runner — hq run [options] -- <cmd>
|
|
145
|
+
registerRunCommand(program);
|
|
146
|
+
// Groups management (subcommand group — hq groups create|delete|add|remove|list|members)
|
|
147
|
+
registerGroupsCommand(program);
|
|
148
|
+
// Worker discovery + sharing (subcommand group — hq workers list|share)
|
|
149
|
+
registerWorkersCommand(program);
|
|
150
|
+
// Cross-company group grants (subcommand group —
|
|
151
|
+
// hq group-grants grant|revoke|outbound|inbound)
|
|
152
|
+
registerGroupGrantsCommand(program);
|
|
153
|
+
// Files ACL management (subcommand group — hq files share|unshare|acl)
|
|
154
|
+
// `registerFilesCommand` returns the `files` group so we can attach the
|
|
155
|
+
// browse-vs-sync subcommands (`hq files browse`/`cat`) onto the same group.
|
|
156
|
+
const filesCmd = registerFilesCommand(program);
|
|
157
|
+
registerFilesBrowseCommands(filesCmd);
|
|
158
|
+
// Comment-only skill improvement loop. Structured suggestion/review commands are
|
|
159
|
+
// intentionally absent; live content changes remain governed by FILE_ACL sync.
|
|
160
|
+
registerSkillCommand(program);
|
|
161
|
+
// Membership management (subcommand group — hq members invite|list|revoke)
|
|
162
|
+
registerMembersCommand(program);
|
|
163
|
+
// People directory (subcommand group — hq people list|search|resolve), reading
|
|
164
|
+
// the local companies/<co>/people store scoped to one company.
|
|
165
|
+
registerPeopleCommand(program);
|
|
166
|
+
registerDmCommand(program);
|
|
167
|
+
registerChannelsCommand(program);
|
|
168
|
+
// Onboarding (top-level — Cognito + vault-service provisioning)
|
|
169
|
+
registerOnboardCommand(program);
|
|
170
|
+
// Feedback (subcommand group — hq feedback bug|feature)
|
|
171
|
+
registerFeedbackCommand(program);
|
|
172
|
+
// Meetings (subcommand group — hq meetings list|get|search|transcript|notes)
|
|
173
|
+
registerMeetingsCommand(program);
|
|
174
|
+
// Sources read surface (subcommand group — hq sources list|get|channels|entities)
|
|
175
|
+
registerSourcesCommand(program);
|
|
176
|
+
// Signals read surface (subcommand group — hq signals list|get|types|entities)
|
|
177
|
+
registerSignalsCommand(program);
|
|
178
|
+
// Company-connected apps via the governed integration gateway
|
|
179
|
+
// (subcommand group — hq integrations list|tools|call|approve|reject)
|
|
180
|
+
registerIntegrationsCommand(program);
|
|
181
|
+
// Skill/personal-overlay mirroring + workers-registry regen. Invoked by the
|
|
182
|
+
// hq-core reindex hook shim (Stop / PostToolUse) and by sync()/rescue() after
|
|
183
|
+
// they change on-disk sources. Keeps a `master-sync` alias for one release.
|
|
184
|
+
// Implementation lives in @indigoai-us/hq-cloud.
|
|
185
|
+
registerReindexCommand(program);
|
|
186
|
+
// Drift-preserving HQ-core re-sync (top-level — `hq rescue`). CLI sibling of
|
|
187
|
+
// the HQ Sync app's "Update / Restore" pill; drives the same replace-rescue.sh
|
|
188
|
+
// shipped from @indigoai-us/hq-cloud.
|
|
189
|
+
registerRescueCommand(program);
|
|
190
|
+
// MCP pack observability (subcommand group — `hq mcp status`). Read-only
|
|
191
|
+
// provenance-based status across BOTH Claude + Codex runtimes (reads `_hqPack`
|
|
192
|
+
// off the configs, NOT linkStatus), with secret-redacted output + `--json`.
|
|
193
|
+
registerMcpCommand(program);
|
|
194
|
+
// Native CRM entity upsert (subcommand group — `hq crm entity upsert`). Wraps
|
|
195
|
+
// POST /crm/entities (the ontology write gate) so an authenticated company
|
|
196
|
+
// member can create/update canonical CRM entities in the company vault.
|
|
197
|
+
registerCrmCommand(program);
|
|
198
|
+
// Company settings (subcommand group — `hq company settings set`). Owner-only
|
|
199
|
+
// toggles for crmEnabled / ontologyEnabled via PUT /company-settings.
|
|
200
|
+
registerCompanyCommand(program);
|
|
201
|
+
// Cloud agent management (subcommand group — `hq agents …`). Rename, reconfigure,
|
|
202
|
+
// start/stop, and tear down a company's fleet agents via the hq-pro /v1/agents
|
|
203
|
+
// control plane — the same routes the web console's agents panel calls.
|
|
204
|
+
registerAgentsCommand(program);
|
|
205
|
+
// Personal Outpost management (subcommand group — `hq outposts …`). List, inspect,
|
|
206
|
+
// enable Codex on, refresh login for, and destroy your EC2 boxes via the hq-pro
|
|
207
|
+
// /outpost/* control plane.
|
|
208
|
+
registerOutpostsCommand(program);
|
|
209
|
+
// Billing (subcommand group — `hq billing …`). Check subscription/card state and
|
|
210
|
+
// mint a shareable Stripe card-capture link — the client side of the paid-
|
|
211
|
+
// provisioning gate for agents & Outposts.
|
|
212
|
+
registerBillingCommand(program);
|
|
213
|
+
// HQ scaffold scripts hosted by the CLI (hidden group — `hq core …`). Not a
|
|
214
|
+
// public surface: every entry is invoked by an HQ skill, hook, or forwarder, and
|
|
215
|
+
// the source-root entries are maintainer tools that must never touch a live
|
|
216
|
+
// install. Registered from a manifest in the module, not wired per script here.
|
|
217
|
+
registerCoreCommands(program);
|
|
218
|
+
// Local qmd search and index management. Kept distinct from `hq reindex`,
|
|
219
|
+
// which converges scaffold-owned files and hooks rather than search data.
|
|
220
|
+
registerSearchCommand(program);
|
|
221
|
+
registerIndexCommand(program);
|
|
222
|
+
// Hook guardrail diagnostics (top-level — `hq doctor`). Read-only, offline
|
|
223
|
+
// verification that HQ's hooks are wired and firing, backed by an extensible
|
|
224
|
+
// check registry so later check families (vault, sync, MCP, …) plug in without
|
|
225
|
+
// engine changes.
|
|
226
|
+
registerDoctorCommand(program);
|
|
227
|
+
// Work mesh (subcommand group — `hq mesh …`). Native REST + cache. Distinct
|
|
228
|
+
// from `hq doctor` (hook guardrails). Does not start MQTT listen.
|
|
229
|
+
registerMeshCommand(program);
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=register-all.js.map
|