@indigoai-us/hq-cli 5.241.0 → 5.243.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 CHANGED
@@ -2,6 +2,37 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.243.0] — 2026-09-27
6
+ ### Added
7
+
8
+ - `hq auth login` remembers the last provider used on this computer and shows the Cognito provider choice page on first login. Only the provider name is stored locally.
9
+
10
+ ### Changed
11
+
12
+ - Internal: moved the accounts, sessions and questions subcommands out of src/commands/lanes.ts; no behaviour change
13
+
14
+ ### Fixed
15
+
16
+ - Removed the unused `cli.network.force-ipv4` hq-flags lookup and forced IPv4
17
+ startup path. The existing Node family-attempt timeout remains unchanged.
18
+ - `hq auth login` continues when it cannot read or save the remembered provider. It prints a dim warning with the state path and error code; a save failure does not turn a successful sign-in into a login failure.
19
+
20
+ ## [5.242.0] — 2026-09-27
21
+
22
+ ### Changed
23
+
24
+ - Removed the completed `lanes.message-compaction-replay`,
25
+ `lanes.outpost-question-visibility`, and
26
+ `lanes.host-scoped-account-homes` gates. Their shipped behaviors now run
27
+ unconditionally.
28
+ - Account-home login and `set-home` no longer require an unrelated active
29
+ company selection when `--company` is omitted; explicit `--company` values
30
+ remain validated.
31
+
32
+ ### Fixed
33
+
34
+ - The `cli.install-path-compatibility` hq-flags key enables pnpm v11+ global-path recognition. On Windows, it also passes drive-path tarballs to tar by filename from the archive directory. The flag defaults to off.
35
+
5
36
  ## [5.241.0] — 2026-09-27
6
37
 
7
38
  ### Fixed
@@ -8447,7 +8447,7 @@ export declare const COMMAND_CATALOG: readonly [{
8447
8447
  readonly description: "Host key (defaults to this host's hostname)";
8448
8448
  }, {
8449
8449
  readonly flags: "--company <slug|uid>";
8450
- readonly description: "Company scope for the host-account-home flag";
8450
+ readonly description: "Company scope for account-home validation";
8451
8451
  }, {
8452
8452
  readonly flags: "--json";
8453
8453
  readonly description: "JSON on stdout (always)";
@@ -8473,7 +8473,7 @@ export declare const COMMAND_CATALOG: readonly [{
8473
8473
  readonly description: "Account home directory";
8474
8474
  }, {
8475
8475
  readonly flags: "--company <slug|uid>";
8476
- readonly description: "Company scope for the host-account-home flag";
8476
+ readonly description: "Company scope for account-home validation";
8477
8477
  }, {
8478
8478
  readonly flags: "--device-auth";
8479
8479
  readonly description: "Use Codex device authentication instead of localhost callback";
@@ -10929,7 +10929,7 @@ export const COMMAND_CATALOG = [
10929
10929
  },
10930
10930
  {
10931
10931
  "flags": "--company <slug|uid>",
10932
- "description": "Company scope for the host-account-home flag"
10932
+ "description": "Company scope for account-home validation"
10933
10933
  },
10934
10934
  {
10935
10935
  "flags": "--json",
@@ -10963,7 +10963,7 @@ export const COMMAND_CATALOG = [
10963
10963
  },
10964
10964
  {
10965
10965
  "flags": "--company <slug|uid>",
10966
- "description": "Company scope for the host-account-home flag"
10966
+ "description": "Company scope for account-home validation"
10967
10967
  },
10968
10968
  {
10969
10969
  "flags": "--device-auth",
@@ -16,31 +16,70 @@
16
16
  import chalk from "chalk";
17
17
  import { browserLogin, clearCachedTokens, loadCachedTokens, isExpiring, loadMachineCreds, CognitoAuthError, } from "@indigoai-us/hq-cloud";
18
18
  import { DEFAULT_COGNITO, refreshCachedSession, resolveCognitoTokenSource, } from "../utils/cognito-session.js";
19
- import { cognitoConfigForLoginProvider } from "../utils/login-provider.js";
19
+ import { resolveLoginProviderSelection, } from "../utils/login-provider.js";
20
+ import { getLastLoginProviderStatePath, loadLastLoginProvider, storeLastLoginProvider, } from "../lib/auth-login-provider-state.js";
20
21
  import { callbackPortBusyGuidance, DEFAULT_CALLBACK_PORT, isCallbackPortBusy, } from "../utils/callback-port-busy.js";
21
- /**
22
- * Decode the (unverified) ID token payload for display purposes only.
23
- * The token was just returned by Cognito's token endpoint, so its contents
24
- * are trusted enough to print — we never use these claims for authorization.
25
- */
26
- function peekIdToken(idToken) {
22
+ /** Decode token claims for local display and provider-memory purposes only. */
23
+ function decodeIdTokenClaims(idToken) {
27
24
  try {
28
25
  const payload = idToken.split(".")[1];
29
26
  if (!payload)
30
- return {};
27
+ return undefined;
31
28
  const pad = payload.length % 4 === 0 ? "" : "=".repeat(4 - (payload.length % 4));
32
29
  const normalized = payload.replace(/-/g, "+").replace(/_/g, "/") + pad;
33
30
  const decoded = JSON.parse(Buffer.from(normalized, "base64").toString("utf-8"));
34
- return {
35
- email: decoded.email,
36
- sub: decoded.sub,
37
- entityType: decoded["custom:entityType"],
38
- entityUid: decoded["custom:entityUid"],
39
- };
31
+ return decoded && typeof decoded === "object" && !Array.isArray(decoded)
32
+ ? decoded
33
+ : undefined;
40
34
  }
41
35
  catch {
42
- return {};
36
+ return undefined;
37
+ }
38
+ }
39
+ function peekIdToken(idToken) {
40
+ const claims = decodeIdTokenClaims(idToken);
41
+ return {
42
+ email: typeof claims?.email === "string" ? claims.email : undefined,
43
+ sub: typeof claims?.sub === "string" ? claims.sub : undefined,
44
+ entityType: typeof claims?.["custom:entityType"] === "string"
45
+ ? claims["custom:entityType"]
46
+ : undefined,
47
+ entityUid: typeof claims?.["custom:entityUid"] === "string"
48
+ ? claims["custom:entityUid"]
49
+ : undefined,
50
+ };
51
+ }
52
+ function errorCode(error) {
53
+ if (error
54
+ && typeof error === "object"
55
+ && "code" in error
56
+ && typeof error.code === "string") {
57
+ return error.code;
43
58
  }
59
+ return "UNKNOWN";
60
+ }
61
+ function providerFromIdToken(idToken) {
62
+ const identities = decodeIdTokenClaims(idToken)?.identities;
63
+ if (!Array.isArray(identities))
64
+ return undefined;
65
+ const providers = new Set();
66
+ for (const identity of identities) {
67
+ if (!identity || typeof identity !== "object" || Array.isArray(identity))
68
+ continue;
69
+ const item = identity;
70
+ const providerName = typeof item.providerName === "string"
71
+ ? item.providerName
72
+ : item.providerType;
73
+ if (typeof providerName !== "string")
74
+ continue;
75
+ const normalized = providerName.trim().toLowerCase();
76
+ if (normalized === "google")
77
+ providers.add("google");
78
+ if (normalized === "microsoft" || normalized === "microsoftpersonal") {
79
+ providers.add("microsoft");
80
+ }
81
+ }
82
+ return providers.size === 1 ? providers.values().next().value : undefined;
44
83
  }
45
84
  /** Display label for the local machine identity (company agents). */
46
85
  function machineIdentityLabel() {
@@ -67,7 +106,25 @@ export function registerAuthCommands(program) {
67
106
  return;
68
107
  }
69
108
  try {
70
- const tokens = await browserLogin(cognitoConfigForLoginProvider(options.provider));
109
+ const canUseRememberedProvider = options.provider === undefined
110
+ && process.env.HQ_COGNITO_IDENTITY_PROVIDER === undefined;
111
+ let rememberedProvider;
112
+ if (canUseRememberedProvider) {
113
+ try {
114
+ rememberedProvider = loadLastLoginProvider();
115
+ }
116
+ catch (error) {
117
+ console.error(chalk.dim(`Could not read provider state at ${getLastLoginProviderStatePath()} (${errorCode(error)}). Continuing to the provider choice page.`));
118
+ }
119
+ }
120
+ const selection = resolveLoginProviderSelection(options.provider, process.env, rememberedProvider);
121
+ const tokens = await browserLogin(selection.config);
122
+ try {
123
+ storeLastLoginProvider(providerFromIdToken(tokens.idToken) ?? selection.providerToRemember);
124
+ }
125
+ catch (error) {
126
+ console.error(chalk.dim(`Could not save provider state at ${getLastLoginProviderStatePath()} (${errorCode(error)}). The provider choice was not saved.`));
127
+ }
71
128
  const who = peekIdToken(tokens.idToken).email ?? "HQ";
72
129
  console.log(chalk.green(`Signed in as ${who}`));
73
130
  console.log(chalk.dim(` Token cached at ~/.hq/cognito-tokens.json (expires ${tokens.expiresAt})`));
@@ -0,0 +1,25 @@
1
+ import type { Ctx, LaneAccountsHandlerDeps } from "./lanes-shared.js";
2
+ export declare function createLaneAccountsHandlers(deps: LaneAccountsHandlerDeps): {
3
+ runAccountsList: (ctx: Ctx, opts: {
4
+ provider?: string;
5
+ }) => Promise<void>;
6
+ runAccountsBalance: (ctx: Ctx, opts: {
7
+ provider?: string;
8
+ apply?: boolean;
9
+ json?: boolean;
10
+ }) => Promise<void>;
11
+ runAccountsLogin: (ctx: Ctx, providerRaw: string, accountId: string, opts: {
12
+ home?: string;
13
+ deviceAuth?: boolean;
14
+ company?: string;
15
+ }) => Promise<void>;
16
+ runAccountsSetHome: (ctx: Ctx, providerRaw: string, accountIdRaw: string, homeRaw: string, opts: {
17
+ host?: string;
18
+ company?: string;
19
+ }) => Promise<void>;
20
+ runAccountsEnable: (ctx: Ctx, providerRaw: string, accountId: string) => Promise<void>;
21
+ runAccountsDisable: (ctx: Ctx, providerRaw: string, accountId: string, opts: {
22
+ reason?: string;
23
+ }) => Promise<void>;
24
+ };
25
+ //# sourceMappingURL=lanes-accounts.d.ts.map