@indigoai-us/hq-cli 5.345.145 → 5.345.147

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,24 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.345.147] — 2026-10-18
6
+
7
+ - Worker registry rebuild now also skips Codex worktrees (`.codex/worktrees/`). Same nested-checkout trap as `.claude/worktrees/`.
8
+ - Worker registry rebuild now skips Claude Code worktrees (`.claude/worktrees/`). A nested HQ checkout under a company project used to land in `core/workers/registry.yaml`, and `hq lanes create` then failed with `worker_tenancy_unresolved`.
9
+
10
+ - HQ bots no longer quit and relaunch the HQ desktop app when they answer a message. Bots now run with the desktop update check turned off, so the app is never restarted in the middle of onboarding or a conversation; the app still updates itself as usual.
11
+ - `hq doctor` now reports a release link that does not open, including one left pointing at a deleted update folder. The result tells you to run `hq rescue -y` again. On Windows without Developer Mode, that retry writes a directory link as a junction and a file link as a copy.
12
+ - The bundled sync engine now uses hq-cloud 6.18.85. `hq outposts refresh-config --company <slug>` re-applies the server's job runner configuration to a running company Outpost without rebuilding it (owner or admin).
13
+ - The bundled sync engine now uses hq-cloud 6.18.87. Sync reports every refused stale upload as a failure instead of skipping it quietly.
14
+ - `hq login --no-browser` and `hq auth login --no-browser` print the sign-in URL and wait without launching a browser. CI and Linux sessions without a display use the same behavior. Remote sign-in instructions include SSH port forwarding.
15
+ - `hq files unshare <path>` reports the number of empty entries removed, distinguishes retained grants from a deleted share, and shows the server’s owner/admin-only reason when cleanup is forbidden.
16
+ - Added the native hook engine scaffold and six-platform build checks, including
17
+ Windows GUI-subsystem builds and a 50-launch no-console test. This prepares
18
+ Windows hook parity; installed hook settings and behavior are unchanged.
19
+
20
+ ## [5.345.146] — 2026-10-17
21
+ - `hq capacity route` and `hq lanes create --account auto` can now use a Claude account whose weekly limit is used up but whose paid extra usage is on. Pass `--allow-extra-usage` to allow it; the account is picked last. Without the flag, the refusal now says extra usage is on and names the flag.
22
+
5
23
  ## [5.345.145] — 2026-10-17
6
24
  - `hq core checkpoint`: the background checkpoint helper now fills in automatic
7
25
  saves that were queued before it started. It writes its own report first,
package/README.md CHANGED
@@ -163,3 +163,17 @@ Use `--target lane:<lane-id>` or
163
163
  `--target session:<claude|codex|grok>:<session-id>` when automatic target
164
164
  detection is not appropriate. Monitor output is framed as script data before
165
165
  it is added to an agent's context.
166
+
167
+ ### Sign in without opening a browser
168
+
169
+ Run `hq login --no-browser` or `hq auth login --no-browser` to print a sign-in
170
+ URL and wait for completion. Open the URL in your browser. HQ also uses this
171
+ mode in CI and on Linux without DISPLAY or WAYLAND_DISPLAY. Existing cached
172
+ sessions are reused.
173
+
174
+ For an SSH host, first connect with `ssh -L 8765:localhost:8765 user@host`,
175
+ then run the login command there and open the printed URL on your computer.
176
+ If your callback port is configured differently, forward that port instead.
177
+ Keep the SSH connection open until login finishes. The sign-in uses a localhost
178
+ callback with PKCE, so there is no device code to enter. It times out after
179
+ 15 minutes. Tokens are cached locally and never printed.
@@ -1170,6 +1170,10 @@ export declare const COMMAND_CATALOG: readonly [{
1170
1170
  readonly flags: "--provider <provider>";
1171
1171
  readonly description: "OAuth provider to use: google, microsoft, or picker";
1172
1172
  readonly hidden: false;
1173
+ }, {
1174
+ readonly flags: "--no-browser";
1175
+ readonly description: "Print the sign-in URL without opening a browser";
1176
+ readonly hidden: false;
1173
1177
  }];
1174
1178
  readonly subcommands: readonly [];
1175
1179
  }, {
@@ -1603,6 +1607,10 @@ export declare const COMMAND_CATALOG: readonly [{
1603
1607
  readonly flags: "--provider <provider>";
1604
1608
  readonly description: "OAuth provider to use: google, microsoft, or picker";
1605
1609
  readonly hidden: false;
1610
+ }, {
1611
+ readonly flags: "--no-browser";
1612
+ readonly description: "Print the sign-in URL without opening a browser";
1613
+ readonly hidden: false;
1606
1614
  }];
1607
1615
  readonly subcommands: readonly [];
1608
1616
  }, {
@@ -2836,7 +2844,7 @@ export declare const COMMAND_CATALOG: readonly [{
2836
2844
  readonly subcommands: readonly [];
2837
2845
  }, {
2838
2846
  readonly name: "unshare";
2839
- readonly description: "Remove a named file access grant, or remove an empty ACL row without --with.";
2847
+ readonly description: "Remove a named file access grant, or remove an empty ACL row or grantee-less entries without --with.";
2840
2848
  readonly aliases: readonly [];
2841
2849
  readonly hidden: false;
2842
2850
  readonly helpOption: true;
@@ -7590,6 +7598,26 @@ export declare const COMMAND_CATALOG: readonly [{
7590
7598
  readonly hidden: false;
7591
7599
  }];
7592
7600
  readonly subcommands: readonly [];
7601
+ }, {
7602
+ readonly name: "refresh-config";
7603
+ readonly description: "Re-apply the server's job runner configuration to the company Outpost (owner or admin)";
7604
+ readonly aliases: readonly [];
7605
+ readonly hidden: false;
7606
+ readonly helpOption: true;
7607
+ readonly helpCommand: false;
7608
+ readonly usage: "[options]";
7609
+ readonly helpText: readonly [];
7610
+ readonly arguments: readonly [];
7611
+ readonly options: readonly [{
7612
+ readonly flags: "--company <slug>";
7613
+ readonly description: "Company slug";
7614
+ readonly hidden: false;
7615
+ }, {
7616
+ readonly flags: "--json";
7617
+ readonly description: "Emit raw JSON";
7618
+ readonly hidden: false;
7619
+ }];
7620
+ readonly subcommands: readonly [];
7593
7621
  }, {
7594
7622
  readonly name: "codex-enable";
7595
7623
  readonly description: "Enable (or retry) Codex on an Outpost";
@@ -10375,6 +10403,10 @@ export declare const COMMAND_CATALOG: readonly [{
10375
10403
  readonly description: "Minimum headroom percent the pick must clear (0-100)";
10376
10404
  readonly hidden: false;
10377
10405
  readonly defaultValue: "15";
10406
+ }, {
10407
+ readonly flags: "--allow-extra-usage";
10408
+ readonly description: "Rank a Claude account whose plan limit is used up but whose paid extra usage is on (ranked last)";
10409
+ readonly hidden: false;
10378
10410
  }, {
10379
10411
  readonly flags: "--json";
10380
10412
  readonly description: "Print the route result as JSON (default)";
@@ -14052,6 +14084,10 @@ export declare const COMMAND_CATALOG: readonly [{
14052
14084
  readonly flags: "--account <id>";
14053
14085
  readonly description: "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)";
14054
14086
  readonly hidden: false;
14087
+ }, {
14088
+ readonly flags: "--allow-extra-usage";
14089
+ readonly description: "With --account auto, allow a Claude account whose plan limit is used up but whose paid extra usage is on; ranked last";
14090
+ readonly hidden: false;
14055
14091
  }, {
14056
14092
  readonly flags: "--model <id>";
14057
14093
  readonly description: "Model id for the provider CLI";
@@ -1402,6 +1402,11 @@ export const COMMAND_CATALOG = [
1402
1402
  "flags": "--provider <provider>",
1403
1403
  "description": "OAuth provider to use: google, microsoft, or picker",
1404
1404
  "hidden": false
1405
+ },
1406
+ {
1407
+ "flags": "--no-browser",
1408
+ "description": "Print the sign-in URL without opening a browser",
1409
+ "hidden": false
1405
1410
  }
1406
1411
  ],
1407
1412
  "subcommands": []
@@ -1917,6 +1922,11 @@ export const COMMAND_CATALOG = [
1917
1922
  "flags": "--provider <provider>",
1918
1923
  "description": "OAuth provider to use: google, microsoft, or picker",
1919
1924
  "hidden": false
1925
+ },
1926
+ {
1927
+ "flags": "--no-browser",
1928
+ "description": "Print the sign-in URL without opening a browser",
1929
+ "hidden": false
1920
1930
  }
1921
1931
  ],
1922
1932
  "subcommands": []
@@ -3409,7 +3419,7 @@ export const COMMAND_CATALOG = [
3409
3419
  },
3410
3420
  {
3411
3421
  "name": "unshare",
3412
- "description": "Remove a named file access grant, or remove an empty ACL row without --with.",
3422
+ "description": "Remove a named file access grant, or remove an empty ACL row or grantee-less entries without --with.",
3413
3423
  "aliases": [],
3414
3424
  "hidden": false,
3415
3425
  "helpOption": true,
@@ -9245,6 +9255,30 @@ export const COMMAND_CATALOG = [
9245
9255
  ],
9246
9256
  "subcommands": []
9247
9257
  },
9258
+ {
9259
+ "name": "refresh-config",
9260
+ "description": "Re-apply the server's job runner configuration to the company Outpost (owner or admin)",
9261
+ "aliases": [],
9262
+ "hidden": false,
9263
+ "helpOption": true,
9264
+ "helpCommand": false,
9265
+ "usage": "[options]",
9266
+ "helpText": [],
9267
+ "arguments": [],
9268
+ "options": [
9269
+ {
9270
+ "flags": "--company <slug>",
9271
+ "description": "Company slug",
9272
+ "hidden": false
9273
+ },
9274
+ {
9275
+ "flags": "--json",
9276
+ "description": "Emit raw JSON",
9277
+ "hidden": false
9278
+ }
9279
+ ],
9280
+ "subcommands": []
9281
+ },
9248
9282
  {
9249
9283
  "name": "codex-enable",
9250
9284
  "description": "Enable (or retry) Codex on an Outpost",
@@ -12573,6 +12607,11 @@ export const COMMAND_CATALOG = [
12573
12607
  "hidden": false,
12574
12608
  "defaultValue": "15"
12575
12609
  },
12610
+ {
12611
+ "flags": "--allow-extra-usage",
12612
+ "description": "Rank a Claude account whose plan limit is used up but whose paid extra usage is on (ranked last)",
12613
+ "hidden": false
12614
+ },
12576
12615
  {
12577
12616
  "flags": "--json",
12578
12617
  "description": "Print the route result as JSON (default)",
@@ -17082,6 +17121,11 @@ export const COMMAND_CATALOG = [
17082
17121
  "description": "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)",
17083
17122
  "hidden": false
17084
17123
  },
17124
+ {
17125
+ "flags": "--allow-extra-usage",
17126
+ "description": "With --account auto, allow a Claude account whose plan limit is used up but whose paid extra usage is on; ranked last",
17127
+ "hidden": false
17128
+ },
17085
17129
  {
17086
17130
  "flags": "--model <id>",
17087
17131
  "description": "Model id for the provider CLI",
@@ -14,13 +14,14 @@
14
14
  * session is kept valid by `hq auth refresh` / `hq-auth-refresh` and consumed
15
15
  * by the deploy + sync skills.
16
16
  */
17
+ import { loginWithBrowserPreference } from "../utils/login-browser.js";
17
18
  import { releaseCurrentPackageUseLease, releasePackageUseLeaseAfterResidentPreload } from "../utils/package-use-lease.js";
18
19
  import { preloadResidentPackageModules, reportResidentPackagePreloadFailure } from "../utils/resident-package-preload.js";
19
20
  import * as fs from "node:fs";
20
21
  import { open, realpath } from "node:fs/promises";
21
22
  import path from "node:path";
22
23
  import chalk from "chalk";
23
- import { browserLogin, clearCachedTokens, loadCachedTokens, isExpiring, loadMachineCreds, CognitoAuthError, } from "@indigoai-us/hq-cloud";
24
+ import { clearCachedTokens, loadCachedTokens, isExpiring, loadMachineCreds, CognitoAuthError, } from "@indigoai-us/hq-cloud";
24
25
  import { DEFAULT_COGNITO, refreshCachedSession, resolveCognitoTokenSource, ensureMachineSessionTokens, personTokenCacheFile, machineTokenCacheFile, loadMachineCachedTokens, } from "../utils/cognito-session.js";
25
26
  // Static (node builtins only): a lazy import here would need a resident
26
27
  // preload entry for the auth-login path.
@@ -212,6 +213,7 @@ export function registerAuthCommands(program) {
212
213
  .command("login")
213
214
  .description("Sign in to HQ — opens the Cognito Hosted UI and caches tokens locally")
214
215
  .option("--provider <provider>", "OAuth provider to use: google, microsoft, or picker")
216
+ .option("--no-browser", "Print the sign-in URL without opening a browser")
215
217
  .action(async (options) => {
216
218
  if (resolveCognitoTokenSource() === "machine") {
217
219
  console.log(chalk.green(`Running as ${machineIdentityLabel()} — sessions mint automatically; no browser login needed.`));
@@ -237,7 +239,7 @@ export function registerAuthCommands(program) {
237
239
  }
238
240
  const selection = resolveLoginProviderSelection(options.provider, process.env, rememberedProvider);
239
241
  await releasePackageUseLeaseAfterResidentPreload(() => preloadResidentPackageModules("auth-login"), reportResidentPackagePreloadFailure, releaseCurrentPackageUseLease);
240
- const tokens = await browserLogin(selection.config);
242
+ const tokens = await loginWithBrowserPreference(selection.config, options.browser);
241
243
  try {
242
244
  storeLastLoginProvider(providerFromIdToken(tokens.idToken) ?? selection.providerToRemember);
243
245
  }
@@ -243,7 +243,7 @@ export function spawnDetachedRun(name, dir) {
243
243
  detached: true,
244
244
  windowsHide: true,
245
245
  stdio: ["ignore", fd, fd],
246
- env: { ...process.env, HQ_NO_UPDATE_CHECK: "1" },
246
+ env: { ...process.env, HQ_NO_UPDATE_CHECK: "1", HQ_NO_ENSURE_HQ_DESKTOP: "1" },
247
247
  });
248
248
  fs.closeSync(fd);
249
249
  child.unref();
@@ -358,6 +358,7 @@ export function registerCapacityCommand(program) {
358
358
  .option("--model <id>", "Model id. Narrows --provider any to the mapped provider")
359
359
  .option("--prefer <list>", "Comma-separated preferred provider order", "claude,codex,grok")
360
360
  .option("--floor <percent>", "Minimum headroom percent the pick must clear (0-100)", "15")
361
+ .option("--allow-extra-usage", "Rank a Claude account whose plan limit is used up but whose paid extra usage is on (ranked last)")
361
362
  .option("--json", "Print the route result as JSON (default)")
362
363
  .option("--text", "Print a single-line text summary instead of JSON")
363
364
  .action((_opts, command) => {
@@ -394,6 +395,7 @@ export function registerCapacityCommand(program) {
394
395
  collectorEnabled: mark ? mark.enabled : null,
395
396
  capacityStale: freshness.stale,
396
397
  lanesError,
398
+ allowExtraUsage: opts.allowExtraUsage === true,
397
399
  });
398
400
  }
399
401
  catch (err) {
@@ -267,7 +267,7 @@ export function registerFilesCommand(program) {
267
267
  });
268
268
  files
269
269
  .command("unshare <prefix>")
270
- .description("Remove a named file access grant, or remove an empty ACL row without --with.")
270
+ .description("Remove a named file access grant, or remove an empty ACL row or grantee-less entries without --with.")
271
271
  .option("--with <principal>", "Person uid, agent uid, email address, group id, or '@all' to remove the grant")
272
272
  .action(async (prefix, opts) => {
273
273
  try {
@@ -328,17 +328,21 @@ export function registerFilesCommand(program) {
328
328
  }
329
329
  if (!res.ok) {
330
330
  if (res.status === 403) {
331
- console.error(chalk.red("Not authorized to remove this ACL row"));
332
- await offerAccessLadder(canonicalPrefix, {
333
- company: files.opts().company,
334
- });
331
+ console.error(chalk.red(body.error ?? "Not authorized to remove this ACL row"));
332
+ console.error(chalk.dim("Ask a company admin to remove this entry."));
335
333
  }
336
334
  else {
337
335
  console.error(chalk.red(body.error ?? "Unable to remove ACL row"));
338
336
  }
339
337
  process.exit(1);
340
338
  }
341
- console.log(chalk.green(`Removed empty ACL pattern '${canonicalPrefix}'. It now follows its parent folder's access, so anyone who can see that parent can see this folder.`));
339
+ const removedCount = body.removedEntries;
340
+ const cleanupMessage = typeof removedCount === "number" && removedCount > 0
341
+ ? `Removed ${removedCount} empty ${removedCount === 1 ? "entry" : "entries"} from '${canonicalPrefix}'. `
342
+ : "";
343
+ console.log(chalk.green(body.aclRemoved === false
344
+ ? `${cleanupMessage || `Removed grantee-less entries from '${canonicalPrefix}'. `}Existing grants remain.`
345
+ : `${cleanupMessage || `Removed empty ACL pattern '${canonicalPrefix}'. `}It now follows its parent folder's access, so anyone who can see that parent can see this folder.`));
342
346
  return;
343
347
  }
344
348
  const res = await vaultApiFetch({
@@ -3483,6 +3483,7 @@ async function runCreate(ctx, opts) {
3483
3483
  collectorEnabled: readCollectorMark(ledgerOptions)?.enabled ?? null,
3484
3484
  capacityStale: capacityViewAge(view.generatedAt, ctx.now().getTime()).stale,
3485
3485
  lanesError: routeLanesError,
3486
+ allowExtraUsage: opts.allowExtraUsage === true,
3486
3487
  });
3487
3488
  if (!result.ok || !result.pick) {
3488
3489
  const resetSuffix = result.next_reset ? `; next reset ${result.next_reset}` : "";
@@ -9935,6 +9936,7 @@ export function registerLanesCommand(parent, deps = {}) {
9935
9936
  .option("--remote-control", "Open a Claude lane in Remote Control using account a for login and the selected account for inference")
9936
9937
  .option("--title <text>", "Human-readable Claude Remote Control session title; required with --remote-control")
9937
9938
  .option("--account <id>", "Provider account id, or 'auto' to pick the account with the most room (all accounts are one pool across companies)")
9939
+ .option("--allow-extra-usage", "With --account auto, allow a Claude account whose plan limit is used up but whose paid extra usage is on; ranked last")
9938
9940
  .option("--model <id>", "Model id for the provider CLI")
9939
9941
  .option("--effort <level>", "Effort level; claude: low|medium|high|xhigh|max, codex: minimal|low|medium|high|xhigh|max|ultra, grok: low|medium|high|xhigh")
9940
9942
  .option("--senior <ref>", "session:<id> | lane:<id> | user")
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * hq login — opens browser for Cognito auth.
3
3
  */
4
+ import { loginWithBrowserPreference } from "../utils/login-browser.js";
4
5
  import { releaseCurrentPackageUseLease, releasePackageUseLeaseAfterResidentPreload } from "../utils/package-use-lease.js";
5
6
  import { preloadResidentPackageModules, reportResidentPackagePreloadFailure } from "../utils/resident-package-preload.js";
6
7
  import chalk from 'chalk';
7
- import { browserLogin, loadCachedTokens, isExpiring } from '@indigoai-us/hq-cloud';
8
+ import { loadCachedTokens, isExpiring } from '@indigoai-us/hq-cloud';
8
9
  import { cognitoConfigForLoginProvider } from '../utils/login-provider.js';
9
10
  import * as readline from "node:readline/promises";
10
11
  import { listActiveMembershipCompanies } from "../lib/mesh/api.js";
@@ -31,6 +32,7 @@ export function registerLoginCommand(program) {
31
32
  .command('login')
32
33
  .description('Authenticate with HQ via Cognito')
33
34
  .option('--provider <provider>', 'OAuth provider to use: google, microsoft, or picker')
35
+ .option("--no-browser", "Print the sign-in URL without opening a browser")
34
36
  .action(async (options) => {
35
37
  let accessToken;
36
38
  let packageUseLeaseReleased = false;
@@ -51,8 +53,7 @@ export function registerLoginCommand(program) {
51
53
  }
52
54
  else {
53
55
  await releaseForInteractiveWait();
54
- console.log('Opening browser for authentication...');
55
- const tokens = await browserLogin(cognitoConfigForLoginProvider(options.provider));
56
+ const tokens = await loginWithBrowserPreference(cognitoConfigForLoginProvider(options.provider), options.browser);
56
57
  const who = peekIdToken(tokens.idToken).email ?? 'HQ';
57
58
  console.log(chalk.green(`Logged in as ${who}`));
58
59
  accessToken = tokens.accessToken;