@indigoai-us/hq-cloud 6.15.98 → 6.15.99

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.
@@ -0,0 +1,40 @@
1
+ /**
2
+ * In-process auth-wait for `hq-sync-runner --watch`.
3
+ *
4
+ * A one-shot run still emits `auth-error` and exits. Watch mode must not:
5
+ * the outpost launcher treats a clean exit as "restart in 10s", which
6
+ * crash-loops discovery/subscribe against an unusable session.
7
+ *
8
+ * Recheck cadence is exported so tests inject a compressed clock without
9
+ * changing production values.
10
+ */
11
+ export declare const AUTH_WAIT_INITIAL_RECHECK_MS = 60000;
12
+ export declare const AUTH_WAIT_STEADY_RECHECK_MS: number;
13
+ export declare const AUTH_WAIT_LIVENESS_INTERVAL_MS: number;
14
+ export declare const AUTH_WAIT_START_MESSAGE = "hq-sync-runner: auth required \u2014 waiting for a valid session (rechecking every 5m)";
15
+ export declare const AUTH_WAIT_RESUME_MESSAGE = "hq-sync-runner: session restored \u2014 resuming sync";
16
+ export declare const AUTH_WAIT_LIVENESS_MESSAGE = "hq-sync-runner: still waiting for a valid session";
17
+ export type AuthWaitOutcome = "resumed" | "stopped";
18
+ export interface WaitForValidAuthOptions {
19
+ /** Return true when a non-interactive session is usable again. */
20
+ probeAuth: () => Promise<boolean>;
21
+ sleep: (ms: number) => Promise<void>;
22
+ log: (line: string) => void;
23
+ /** Wall/fake clock for the 30-minute liveness line. Defaults to Date.now. */
24
+ now?: () => number;
25
+ isStopped?: () => boolean;
26
+ /** Resolves when the runner is shutting down so a pending sleep can wake. */
27
+ stoppedSignal?: Promise<void>;
28
+ initialRecheckMs?: number;
29
+ steadyRecheckMs?: number;
30
+ livenessIntervalMs?: number;
31
+ }
32
+ /**
33
+ * Park the watch runner until a session is valid again, or shutdown fires.
34
+ *
35
+ * One start line, then a 60s first recheck, then a steady 5-minute cadence.
36
+ * Failed rechecks are silent except for at most one liveness line per 30
37
+ * minutes. The only remote call is `probeAuth` itself.
38
+ */
39
+ export declare function waitForValidAuth(opts: WaitForValidAuthOptions): Promise<AuthWaitOutcome>;
40
+ //# sourceMappingURL=sync-runner-auth-wait.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-runner-auth-wait.d.ts","sourceRoot":"","sources":["../../src/bin/sync-runner-auth-wait.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,4BAA4B,QAAS,CAAC;AACnD,eAAO,MAAM,2BAA2B,QAAa,CAAC;AACtD,eAAO,MAAM,8BAA8B,QAAc,CAAC;AAE1D,eAAO,MAAM,uBAAuB,2FACiD,CAAC;AACtF,eAAO,MAAM,wBAAwB,0DACe,CAAC;AACrD,eAAO,MAAM,0BAA0B,sDACc,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,6EAA6E;IAC7E,aAAa,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAgBD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,eAAe,CAAC,CAuC1B"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * In-process auth-wait for `hq-sync-runner --watch`.
3
+ *
4
+ * A one-shot run still emits `auth-error` and exits. Watch mode must not:
5
+ * the outpost launcher treats a clean exit as "restart in 10s", which
6
+ * crash-loops discovery/subscribe against an unusable session.
7
+ *
8
+ * Recheck cadence is exported so tests inject a compressed clock without
9
+ * changing production values.
10
+ */
11
+ export const AUTH_WAIT_INITIAL_RECHECK_MS = 60_000;
12
+ export const AUTH_WAIT_STEADY_RECHECK_MS = 5 * 60_000;
13
+ export const AUTH_WAIT_LIVENESS_INTERVAL_MS = 30 * 60_000;
14
+ export const AUTH_WAIT_START_MESSAGE = "hq-sync-runner: auth required — waiting for a valid session (rechecking every 5m)";
15
+ export const AUTH_WAIT_RESUME_MESSAGE = "hq-sync-runner: session restored — resuming sync";
16
+ export const AUTH_WAIT_LIVENESS_MESSAGE = "hq-sync-runner: still waiting for a valid session";
17
+ async function sleepUntilStopped(ms, sleep, isStopped, stoppedSignal) {
18
+ if (isStopped())
19
+ return;
20
+ if (!stoppedSignal) {
21
+ await sleep(ms);
22
+ return;
23
+ }
24
+ await Promise.race([sleep(ms), stoppedSignal]);
25
+ }
26
+ /**
27
+ * Park the watch runner until a session is valid again, or shutdown fires.
28
+ *
29
+ * One start line, then a 60s first recheck, then a steady 5-minute cadence.
30
+ * Failed rechecks are silent except for at most one liveness line per 30
31
+ * minutes. The only remote call is `probeAuth` itself.
32
+ */
33
+ export async function waitForValidAuth(opts) {
34
+ const isStopped = opts.isStopped ?? (() => false);
35
+ const now = opts.now ?? Date.now;
36
+ const initialRecheckMs = opts.initialRecheckMs ?? AUTH_WAIT_INITIAL_RECHECK_MS;
37
+ const steadyRecheckMs = opts.steadyRecheckMs ?? AUTH_WAIT_STEADY_RECHECK_MS;
38
+ const livenessIntervalMs = opts.livenessIntervalMs ?? AUTH_WAIT_LIVENESS_INTERVAL_MS;
39
+ if (isStopped())
40
+ return "stopped";
41
+ opts.log(AUTH_WAIT_START_MESSAGE);
42
+ let delayMs = initialRecheckMs;
43
+ let lastLivenessAt = now();
44
+ while (!isStopped()) {
45
+ await sleepUntilStopped(delayMs, opts.sleep, isStopped, opts.stoppedSignal);
46
+ if (isStopped())
47
+ return "stopped";
48
+ let valid = false;
49
+ try {
50
+ valid = await opts.probeAuth();
51
+ }
52
+ catch {
53
+ valid = false;
54
+ }
55
+ if (isStopped())
56
+ return "stopped";
57
+ if (valid) {
58
+ opts.log(AUTH_WAIT_RESUME_MESSAGE);
59
+ return "resumed";
60
+ }
61
+ delayMs = steadyRecheckMs;
62
+ const t = now();
63
+ if (t - lastLivenessAt >= livenessIntervalMs) {
64
+ opts.log(AUTH_WAIT_LIVENESS_MESSAGE);
65
+ lastLivenessAt = t;
66
+ }
67
+ }
68
+ return "stopped";
69
+ }
70
+ //# sourceMappingURL=sync-runner-auth-wait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-runner-auth-wait.js","sourceRoot":"","sources":["../../src/bin/sync-runner-auth-wait.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC;AACnD,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,GAAG,MAAM,CAAC;AACtD,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,GAAG,MAAM,CAAC;AAE1D,MAAM,CAAC,MAAM,uBAAuB,GAClC,mFAAmF,CAAC;AACtF,MAAM,CAAC,MAAM,wBAAwB,GACnC,kDAAkD,CAAC;AACrD,MAAM,CAAC,MAAM,0BAA0B,GACrC,mDAAmD,CAAC;AAmBtD,KAAK,UAAU,iBAAiB,CAC9B,EAAU,EACV,KAAoC,EACpC,SAAwB,EACxB,aAAwC;IAExC,IAAI,SAAS,EAAE;QAAE,OAAO;IACxB,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IACD,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAA6B;IAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,4BAA4B,CAAC;IAC/E,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,2BAA2B,CAAC;IAC5E,MAAM,kBAAkB,GACtB,IAAI,CAAC,kBAAkB,IAAI,8BAA8B,CAAC;IAE5D,IAAI,SAAS,EAAE;QAAE,OAAO,SAAS,CAAC;IAElC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IAClC,IAAI,OAAO,GAAG,gBAAgB,CAAC;IAC/B,IAAI,cAAc,GAAG,GAAG,EAAE,CAAC;IAE3B,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;QACpB,MAAM,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5E,IAAI,SAAS,EAAE;YAAE,OAAO,SAAS,CAAC;QAElC,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC;QACD,IAAI,SAAS,EAAE;YAAE,OAAO,SAAS,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YACnC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,GAAG,eAAe,CAAC;QAC1B,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,GAAG,cAAc,IAAI,kBAAkB,EAAE,CAAC;YAC7C,IAAI,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;YACrC,cAAc,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sync-runner-auth-wait.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-runner-auth-wait.test.d.ts","sourceRoot":"","sources":["../../src/bin/sync-runner-auth-wait.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,148 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { AUTH_WAIT_INITIAL_RECHECK_MS, AUTH_WAIT_LIVENESS_INTERVAL_MS, AUTH_WAIT_LIVENESS_MESSAGE, AUTH_WAIT_RESUME_MESSAGE, AUTH_WAIT_START_MESSAGE, AUTH_WAIT_STEADY_RECHECK_MS, waitForValidAuth, } from "./sync-runner-auth-wait.js";
3
+ function pendingSleep() {
4
+ const delays = [];
5
+ const waiters = [];
6
+ return {
7
+ delays,
8
+ sleep: (ms) => {
9
+ delays.push(ms);
10
+ return new Promise((resolve) => {
11
+ waiters.push(resolve);
12
+ });
13
+ },
14
+ tick() {
15
+ const resolve = waiters.shift();
16
+ if (!resolve)
17
+ throw new Error("auth-wait sleep was not pending");
18
+ resolve();
19
+ },
20
+ pendingCount: () => waiters.length,
21
+ };
22
+ }
23
+ async function waitUntil(pred, label) {
24
+ for (let i = 0; i < 80; i++) {
25
+ if (pred())
26
+ return;
27
+ await Promise.resolve();
28
+ }
29
+ throw new Error(`timed out waiting for ${label}`);
30
+ }
31
+ describe("waitForValidAuth", () => {
32
+ it("sleeps the initial interval before the first probe, then the steady cadence", async () => {
33
+ const clock = pendingSleep();
34
+ const log = vi.fn();
35
+ let probes = 0;
36
+ const probeAuth = vi.fn(async () => {
37
+ probes += 1;
38
+ return probes >= 2;
39
+ });
40
+ const done = waitForValidAuth({
41
+ probeAuth,
42
+ sleep: clock.sleep,
43
+ log,
44
+ });
45
+ await waitUntil(() => clock.pendingCount() === 1, "initial auth-wait sleep");
46
+ expect(log).toHaveBeenCalledTimes(1);
47
+ expect(log).toHaveBeenCalledWith(AUTH_WAIT_START_MESSAGE);
48
+ expect(probeAuth).not.toHaveBeenCalled();
49
+ expect(clock.delays).toEqual([AUTH_WAIT_INITIAL_RECHECK_MS]);
50
+ clock.tick();
51
+ await waitUntil(() => clock.delays.length === 2 && probeAuth.mock.calls.length === 1, "steady auth-wait sleep after first failed probe");
52
+ expect(clock.delays).toEqual([
53
+ AUTH_WAIT_INITIAL_RECHECK_MS,
54
+ AUTH_WAIT_STEADY_RECHECK_MS,
55
+ ]);
56
+ clock.tick();
57
+ await expect(done).resolves.toBe("resumed");
58
+ expect(probeAuth).toHaveBeenCalledTimes(2);
59
+ expect(log.mock.calls.map((call) => call[0])).toEqual([
60
+ AUTH_WAIT_START_MESSAGE,
61
+ AUTH_WAIT_RESUME_MESSAGE,
62
+ ]);
63
+ });
64
+ it("returns stopped without probing when shutdown fires during the first sleep", async () => {
65
+ const clock = pendingSleep();
66
+ const log = vi.fn();
67
+ const probeAuth = vi.fn(async () => true);
68
+ let stopped = false;
69
+ let resolveStop = () => { };
70
+ const stoppedSignal = new Promise((resolve) => {
71
+ resolveStop = resolve;
72
+ });
73
+ const done = waitForValidAuth({
74
+ probeAuth,
75
+ sleep: clock.sleep,
76
+ log,
77
+ isStopped: () => stopped,
78
+ stoppedSignal,
79
+ });
80
+ await waitUntil(() => clock.pendingCount() === 1, "initial auth-wait sleep");
81
+ stopped = true;
82
+ resolveStop();
83
+ await expect(done).resolves.toBe("stopped");
84
+ expect(probeAuth).not.toHaveBeenCalled();
85
+ expect(log).toHaveBeenCalledTimes(1);
86
+ expect(log).toHaveBeenCalledWith(AUTH_WAIT_START_MESSAGE);
87
+ });
88
+ it("treats a throwing probe as still-invalid and keeps waiting", async () => {
89
+ const clock = pendingSleep();
90
+ const log = vi.fn();
91
+ const probeAuth = vi
92
+ .fn()
93
+ .mockRejectedValueOnce(new Error("invalid_grant"))
94
+ .mockResolvedValueOnce(true);
95
+ const done = waitForValidAuth({
96
+ probeAuth,
97
+ sleep: clock.sleep,
98
+ log,
99
+ });
100
+ await waitUntil(() => clock.pendingCount() === 1, "initial auth-wait sleep");
101
+ clock.tick();
102
+ await waitUntil(() => clock.delays.length === 2 && probeAuth.mock.calls.length === 1, "steady auth-wait sleep after throwing probe");
103
+ expect(clock.delays).toEqual([
104
+ AUTH_WAIT_INITIAL_RECHECK_MS,
105
+ AUTH_WAIT_STEADY_RECHECK_MS,
106
+ ]);
107
+ clock.tick();
108
+ await expect(done).resolves.toBe("resumed");
109
+ expect(probeAuth).toHaveBeenCalledTimes(2);
110
+ });
111
+ it("emits at most one liveness line per liveness interval while waiting", async () => {
112
+ const clock = pendingSleep();
113
+ const log = vi.fn();
114
+ const probeAuth = vi.fn(async () => false);
115
+ let now = 1_000;
116
+ let stopped = false;
117
+ const done = waitForValidAuth({
118
+ probeAuth,
119
+ sleep: clock.sleep,
120
+ log,
121
+ now: () => now,
122
+ isStopped: () => stopped,
123
+ livenessIntervalMs: AUTH_WAIT_LIVENESS_INTERVAL_MS,
124
+ });
125
+ await waitUntil(() => clock.pendingCount() === 1, "initial auth-wait sleep");
126
+ now += AUTH_WAIT_INITIAL_RECHECK_MS;
127
+ clock.tick();
128
+ await waitUntil(() => clock.delays.length === 2, "steady sleep after first failed probe");
129
+ expect(log.mock.calls.map((call) => call[0])).toEqual([
130
+ AUTH_WAIT_START_MESSAGE,
131
+ ]);
132
+ now += AUTH_WAIT_LIVENESS_INTERVAL_MS;
133
+ clock.tick();
134
+ await waitUntil(() => log.mock.calls.some((call) => call[0] === AUTH_WAIT_LIVENESS_MESSAGE), "liveness line");
135
+ expect(log.mock.calls.map((call) => call[0])).toEqual([
136
+ AUTH_WAIT_START_MESSAGE,
137
+ AUTH_WAIT_LIVENESS_MESSAGE,
138
+ ]);
139
+ now += AUTH_WAIT_STEADY_RECHECK_MS;
140
+ clock.tick();
141
+ await waitUntil(() => clock.delays.length === 4, "next sleep after liveness probe");
142
+ expect(log.mock.calls.filter((call) => call[0] === AUTH_WAIT_LIVENESS_MESSAGE)).toHaveLength(1);
143
+ stopped = true;
144
+ clock.tick();
145
+ await expect(done).resolves.toBe("stopped");
146
+ });
147
+ });
148
+ //# sourceMappingURL=sync-runner-auth-wait.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-runner-auth-wait.test.js","sourceRoot":"","sources":["../../src/bin/sync-runner-auth-wait.test.ts"],"names":[],"mappings":"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"}
@@ -2383,7 +2383,7 @@ export async function runWatchLoop(argv, parsed, deps, runtime) {
2383
2383
  try {
2384
2384
  while (!stopped) {
2385
2385
  if (coordinatorAuthRequired)
2386
- return 0;
2386
+ return runtime.authRequiredPassExit;
2387
2387
  pollTick++;
2388
2388
  areaAutoMigration.onTick();
2389
2389
  const pending = takePendingWatcherChange();
@@ -2557,10 +2557,10 @@ export async function runWatchLoop(argv, parsed, deps, runtime) {
2557
2557
  }
2558
2558
  const exitCode = passExitCode(result);
2559
2559
  if (exitCode === runtime.authRequiredPassExit) {
2560
- // The pass already emitted auth-error. Stop the unattended loop but
2561
- // keep the process exit successful so desktop/manual consumers treat
2562
- // this as a reauth state, not a crash.
2563
- return 0;
2560
+ // The pass already emitted auth-error. Hand the sentinel to the
2561
+ // outer watch wrapper so it can park in-process (auth-wait) instead
2562
+ // of exiting and letting the launcher relaunch every 10s.
2563
+ return runtime.authRequiredPassExit;
2564
2564
  }
2565
2565
  else if (exitCode === TRANSIENT_NETWORK_EXIT) {
2566
2566
  // The machine was briefly offline (the discovery fetch failed after