@indigoai-us/hq-cli 5.345.148 → 5.345.150

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.
Files changed (83) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +2 -0
  3. package/dist/command-catalog.generated.d.ts +62 -14
  4. package/dist/command-catalog.generated.js +74 -14
  5. package/dist/command-help.js +2 -1
  6. package/dist/commands/_patterns.d.ts +6 -0
  7. package/dist/commands/_patterns.js +6 -0
  8. package/dist/commands/access.d.ts +45 -2
  9. package/dist/commands/access.js +537 -223
  10. package/dist/commands/billing-usage.d.ts +33 -2
  11. package/dist/commands/billing-usage.js +75 -4
  12. package/dist/commands/bot.js +2 -2
  13. package/dist/commands/channels.d.ts +27 -0
  14. package/dist/commands/channels.js +108 -4
  15. package/dist/commands/core-refresh-vault-access-native.d.ts +16 -0
  16. package/dist/commands/core-refresh-vault-access-native.js +142 -9
  17. package/dist/commands/core.js +4 -1
  18. package/dist/commands/dm.js +9 -1
  19. package/dist/commands/groups.js +9 -6
  20. package/dist/commands/install-global.d.ts +1 -8
  21. package/dist/commands/install-global.js +11 -27
  22. package/dist/commands/lanes-questions.js +7 -4
  23. package/dist/commands/lanes.js +13 -6
  24. package/dist/commands/library-add.d.ts +31 -1
  25. package/dist/commands/library-add.js +69 -2
  26. package/dist/commands/library.js +37 -3
  27. package/dist/commands/members.d.ts +35 -0
  28. package/dist/commands/members.js +65 -14
  29. package/dist/commands/reindex.js +19 -0
  30. package/dist/commands/secrets.d.ts +5 -0
  31. package/dist/commands/secrets.js +11 -6
  32. package/dist/hook-engine-path.js +10 -3
  33. package/dist/hq-cloud-sync-runner/bin/sync-runner.js +63282 -62480
  34. package/dist/hq-cloud-sync-runner/package.json +1 -1
  35. package/dist/index.d.ts +10 -0
  36. package/dist/index.js +70 -5
  37. package/dist/lazy-commands.js +2 -0
  38. package/dist/lib/billing/usage-cost.d.ts +31 -1
  39. package/dist/lib/billing/usage-cost.js +46 -0
  40. package/dist/lib/db/local.d.ts +2 -2
  41. package/dist/lib/db/local.js +2 -2
  42. package/dist/lib/db/sql.js +2 -2
  43. package/dist/lib/db/sqlite-binding.d.ts +22 -0
  44. package/dist/lib/db/sqlite-binding.js +168 -0
  45. package/dist/lib/doctor/checks/anywhere.d.ts +12 -0
  46. package/dist/lib/doctor/checks/anywhere.js +63 -12
  47. package/dist/lib/doctor/checks/cli-path.d.ts +2 -1
  48. package/dist/lib/doctor/checks/cli-path.js +2 -1
  49. package/dist/lib/doctor/checks/hook-engine.js +2 -1
  50. package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
  51. package/dist/lib/flag-registry-worker-source.generated.js +1 -1
  52. package/dist/lib/hook-engine/reconcile.d.ts +9 -0
  53. package/dist/lib/hook-engine/reconcile.js +134 -0
  54. package/dist/lib/hook-engine/registration.d.ts +17 -0
  55. package/dist/lib/hook-engine/registration.js +50 -0
  56. package/dist/lib/install/claude-targets.d.ts +2 -1
  57. package/dist/lib/install/claude-targets.js +8 -3
  58. package/dist/lib/install/codex-targets.d.ts +3 -0
  59. package/dist/lib/install/codex-targets.js +15 -4
  60. package/dist/lib/install/hook-target.d.ts +9 -0
  61. package/dist/lib/install/hook-target.js +39 -0
  62. package/dist/lib/lanes/index.d.ts +1 -1
  63. package/dist/lib/lanes/index.js +1 -1
  64. package/dist/lib/lanes/store.d.ts +11 -0
  65. package/dist/lib/lanes/store.js +20 -0
  66. package/dist/lib/lanes/watch.js +5 -3
  67. package/dist/lib/windows/console-encoding.d.ts +24 -0
  68. package/dist/lib/windows/console-encoding.js +83 -0
  69. package/dist/lib/windows/install-followup.d.ts +35 -0
  70. package/dist/lib/windows/install-followup.js +142 -0
  71. package/dist/lib/windows/user-path.d.ts +80 -3
  72. package/dist/lib/windows/user-path.js +187 -26
  73. package/dist/main.js +2 -1
  74. package/dist/unknown-command.d.ts +18 -0
  75. package/dist/unknown-command.js +88 -0
  76. package/dist/utils/cognito-session.d.ts +8 -0
  77. package/dist/utils/cognito-session.js +14 -2
  78. package/dist/utils/hook-trust.d.ts +9 -0
  79. package/dist/utils/hook-trust.js +30 -2
  80. package/dist/utils/qmd-native-binding-error.js +3 -1
  81. package/dist/utils/resolve-executable.d.ts +2 -0
  82. package/dist/utils/resolve-executable.js +6 -2
  83. package/package.json +9 -9
@@ -267,6 +267,18 @@ export function isMachineCredsFileEnvSet(env = process.env) {
267
267
  export function defaultMachineCredsFile(home = os.homedir()) {
268
268
  return path.join(home, ".hq-agent", "machine-creds.json");
269
269
  }
270
+ /**
271
+ * Env switch a parent process sets so a child `hq` never opens a browser
272
+ * sign-in. A hook-driven helper (SessionStart's refresh-vault-access) cannot
273
+ * complete a browser login, and a child waiting on one outlives its caller.
274
+ */
275
+ export const HQ_NO_BROWSER_LOGIN_ENV = "HQ_NO_BROWSER_LOGIN";
276
+ /** An explicit `interactive` option wins; otherwise interactive unless the env switch is "1". */
277
+ export function resolveInteractiveLogin(options, env = process.env) {
278
+ if (options.interactive !== undefined)
279
+ return options.interactive;
280
+ return env[HQ_NO_BROWSER_LOGIN_ENV]?.trim() !== "1";
281
+ }
270
282
  /**
271
283
  * Align `process.env.HQ_MACHINE_CREDS_FILE` with a (possibly synthetic) `env`
272
284
  * for the duration of `fn`, so hq-cloud's `isMachineIdentity()` sees the same
@@ -971,7 +983,7 @@ export async function ensureCognitoToken(options = {}) {
971
983
  return withTokenStateDirSection(() => ensureCognitoTokenUnserialized(options));
972
984
  }
973
985
  async function ensureCognitoTokenUnserialized(options) {
974
- const interactive = options.interactive ?? true;
986
+ const interactive = resolveInteractiveLogin(options);
975
987
  // Machine identities (company agents) mint sessions on demand via
976
988
  // USER_PASSWORD_AUTH — no refresh-token dance, no browser. The vault API's
977
989
  // JWT authorizer accepts ID tokens, and the agent's identity claims
@@ -1062,7 +1074,7 @@ export async function ensureCognitoIdToken(options = {}) {
1062
1074
  return withTokenStateDirSection(() => ensureCognitoIdTokenUnserialized(options));
1063
1075
  }
1064
1076
  async function ensureCognitoIdTokenUnserialized(options) {
1065
- const interactive = options.interactive ?? true;
1077
+ const interactive = resolveInteractiveLogin(options);
1066
1078
  if (options.signal?.aborted)
1067
1079
  throw options.signal.reason ?? new Error("Token acquisition was aborted");
1068
1080
  if (wantsMachineCognitoTokens(options)) {
@@ -1,3 +1,5 @@
1
+ import { findExecutableOnPath } from './resolve-executable.js';
2
+ import { type SpawnPlan } from './windows-spawn.js';
1
3
  export interface CodexRpcClient {
2
4
  request(method: string, params: unknown): Promise<unknown>;
3
5
  close(): Promise<void>;
@@ -49,6 +51,13 @@ export interface RuntimeHookTrustResult {
49
51
  trusted: number;
50
52
  reason?: string;
51
53
  }
54
+ /**
55
+ * How to launch Codex. npm installs Codex on Windows as a `codex.cmd` shim,
56
+ * which `spawn('codex')` cannot find (ENOENT) and Node refuses to run without a
57
+ * shell, so a bare name is resolved through PATH + PATHEXT and a batch shim is
58
+ * routed through the escaped cmd.exe plan.
59
+ */
60
+ export declare function planCodexLaunch(executable: string, args: readonly string[], env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, find?: typeof findExecutableOnPath): SpawnPlan;
52
61
  /** Start a short-lived Codex app-server and complete its JSONL handshake. */
53
62
  export declare function createCodexAppServerClient(cwd: string, executable?: string, args?: string[]): Promise<CodexRpcClient>;
54
63
  /** Trust only hooks declared by this HQ root's project `.codex/` layer. */
@@ -8,6 +8,8 @@ import * as readline from 'node:readline';
8
8
  // read->merge->write, backup before the first byte, temp+fsync+rename commit)
9
9
  // rather than a bare readFile/writeFile pair.
10
10
  import { acquireLock, atomicReplace, backupConfig, realpathOrSelf, releaseLock, restoreFromBackup, } from '../commands/mcp-registration.js';
11
+ import { findExecutableOnPath } from './resolve-executable.js';
12
+ import { planResolvedCommandSpawn } from './windows-spawn.js';
11
13
  /**
12
14
  * The home directory every runtime's config is resolved under.
13
15
  *
@@ -23,6 +25,11 @@ import { acquireLock, atomicReplace, backupConfig, realpathOrSelf, releaseLock,
23
25
  export function defaultHomeDir() {
24
26
  return process.env.HOME?.trim() ? process.env.HOME : os.homedir();
25
27
  }
28
+ const RUNTIME_LABEL = {
29
+ codex: 'Codex',
30
+ grok: 'Grok',
31
+ claude: 'Claude Code',
32
+ };
26
33
  const CODEX_REQUEST_TIMEOUT_MS = 10_000;
27
34
  function errorMessage(value) {
28
35
  return value instanceof Error ? value.message : String(value);
@@ -77,11 +84,32 @@ function hqProjectHooks(hqRoot, hooks) {
77
84
  !hook.isManaged &&
78
85
  isWithin(path.resolve(hook.sourcePath), codexLayer));
79
86
  }
87
+ /**
88
+ * How to launch Codex. npm installs Codex on Windows as a `codex.cmd` shim,
89
+ * which `spawn('codex')` cannot find (ENOENT) and Node refuses to run without a
90
+ * shell, so a bare name is resolved through PATH + PATHEXT and a batch shim is
91
+ * routed through the escaped cmd.exe plan.
92
+ */
93
+ export function planCodexLaunch(executable, args, env = process.env, platform = process.platform, find = findExecutableOnPath) {
94
+ let command = executable;
95
+ if (platform === 'win32' && !path.win32.isAbsolute(executable) && !/[\\/]/.test(executable)) {
96
+ const resolved = find(executable, env.PATH ?? env.Path ?? '', platform, env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM');
97
+ if (!resolved) {
98
+ throw new Error(`Codex CLI not found on PATH (looked for ${executable}.exe and ${executable}.cmd); install Codex or add it to PATH, then rerun \`hq reindex\``);
99
+ }
100
+ command = resolved;
101
+ }
102
+ return planResolvedCommandSpawn(command, args, env, platform);
103
+ }
80
104
  /** Start a short-lived Codex app-server and complete its JSONL handshake. */
81
105
  export async function createCodexAppServerClient(cwd, executable = 'codex', args = ['app-server']) {
82
- const child = spawn(executable, args, {
106
+ const plan = planCodexLaunch(executable, args);
107
+ const child = spawn(plan.cmd, plan.args, {
83
108
  cwd,
84
109
  stdio: ['pipe', 'pipe', 'pipe'],
110
+ shell: plan.shell,
111
+ windowsHide: true,
112
+ ...(plan.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
85
113
  });
86
114
  const lines = readline.createInterface({ input: child.stdout });
87
115
  const pending = new Map();
@@ -692,7 +720,7 @@ export async function trustHqRuntimeHooks(hqRoot, deps = DEFAULT_DEPS, options =
692
720
  }
693
721
  }
694
722
  else if (result.status === 'failed') {
695
- console.warn(`reindex: could not trust ${result.runtime} HQ hooks: ${result.reason ?? 'unknown error'}`);
723
+ console.warn(`reindex: could not trust ${result.runtime} HQ hooks: ${result.reason ?? 'unknown error'}. ${RUNTIME_LABEL[result.runtime]} will not run HQ hooks until trust succeeds; fix the error above and rerun \`hq reindex\`.`);
696
724
  }
697
725
  }
698
726
  return results;
@@ -48,7 +48,9 @@ export const QMD_NATIVE_BINDING_REMEDY = "hq's local search index can't start: i
48
48
  "not built during install. pnpm 10 skips dependency build scripts by default, " +
49
49
  "which leaves better-sqlite3 uncompiled. Approve the build and reinstall — for " +
50
50
  "a global install run `pnpm approve-builds -g better-sqlite3` (drop -g for a " +
51
- "local project) — or reinstall hq with npm, then run the command again.";
51
+ "local project). npm 11.16 and later skip install scripts unless you opt in; reinstall with " +
52
+ "`npm install -g @indigoai-us/hq-cli --allow-scripts=better-sqlite3`. " +
53
+ "Or reinstall hq with npm, then run the command again.";
52
54
  /**
53
55
  * The text to inspect. For a QmdExitError the captured stderr/stdout is the qmd
54
56
  * process's real diagnostic; the synthesized `message` (which embeds the user's
@@ -1,2 +1,4 @@
1
+ /** First executable file on PATH for `command` (PATHEXT-expanded on Windows), or undefined. */
2
+ export declare function findExecutableOnPath(command: string, pathValue?: string, platform?: NodeJS.Platform, pathExt?: string): string | undefined;
1
3
  export declare function isExecutableOnPath(command: string, pathValue?: string, platform?: NodeJS.Platform, pathExt?: string): boolean;
2
4
  //# sourceMappingURL=resolve-executable.d.ts.map
@@ -9,8 +9,9 @@ function executableCandidates(command, pathValue = process.env.PATH ?? '', platf
9
9
  : pathValue.split(platform === 'win32' ? ';' : path.delimiter).filter(Boolean).flatMap((directory) => extensions.map((extension) => path.join(directory, `${command}${extension}`)));
10
10
  return candidates;
11
11
  }
12
- export function isExecutableOnPath(command, pathValue = process.env.PATH ?? '', platform = process.platform, pathExt = process.env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM') {
13
- return executableCandidates(command, pathValue, platform, pathExt).some((candidate) => {
12
+ /** First executable file on PATH for `command` (PATHEXT-expanded on Windows), or undefined. */
13
+ export function findExecutableOnPath(command, pathValue = process.env.PATH ?? '', platform = process.platform, pathExt = process.env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM') {
14
+ return executableCandidates(command, pathValue, platform, pathExt).find((candidate) => {
14
15
  try {
15
16
  fs.accessSync(candidate, fs.constants.X_OK);
16
17
  return fs.statSync(candidate).isFile();
@@ -20,4 +21,7 @@ export function isExecutableOnPath(command, pathValue = process.env.PATH ?? '',
20
21
  }
21
22
  });
22
23
  }
24
+ export function isExecutableOnPath(command, pathValue = process.env.PATH ?? '', platform = process.platform, pathExt = process.env.PATHEXT ?? '.EXE;.CMD;.BAT;.COM') {
25
+ return findExecutableOnPath(command, pathValue, platform, pathExt) !== undefined;
26
+ }
23
27
  //# sourceMappingURL=resolve-executable.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.345.148",
3
+ "version": "5.345.150",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -42,7 +42,7 @@
42
42
  "check:lanes-module-cycles": "node scripts/check-lanes-module-cycles.mjs",
43
43
  "vitest": "vitest",
44
44
  "clean": "rm -rf dist",
45
- "postinstall": "node scripts/install-hook-engine.mjs && node scripts/mesh-daemon-if-stale.mjs || node -e \"process.exit(0)\"",
45
+ "postinstall": "node scripts/install-hook-engine.mjs || node -e \"process.exit(0)\"",
46
46
  "prepare": "husky || true",
47
47
  "check:no-hermes": "bash scripts/check-no-hermes.sh",
48
48
  "prepack": "node scripts/hook-engine-manifest.mjs",
@@ -52,7 +52,7 @@
52
52
  "@aws-sdk/client-iot-data-plane": "^3.1096.0",
53
53
  "@aws-sdk/client-s3": "^3.1049.0",
54
54
  "@aws-sdk/dsql-signer": "^3.1146.0",
55
- "@indigoai-us/hq-cloud": "~6.18.88",
55
+ "@indigoai-us/hq-cloud": "~6.18.90",
56
56
  "@indigoai-us/hq-flags-client": "^0.1.2",
57
57
  "@modelcontextprotocol/sdk": "1.29.0",
58
58
  "@sentry/node": "^10.49.0",
@@ -114,11 +114,11 @@
114
114
  "*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}": "eslint --cache --no-error-on-unmatched-pattern"
115
115
  },
116
116
  "optionalDependencies": {
117
- "@indigoai-us/hq-hook-win32-x64": "5.345.148",
118
- "@indigoai-us/hq-hook-win32-arm64": "5.345.148",
119
- "@indigoai-us/hq-hook-darwin-x64": "5.345.148",
120
- "@indigoai-us/hq-hook-darwin-arm64": "5.345.148",
121
- "@indigoai-us/hq-hook-linux-x64": "5.345.148",
122
- "@indigoai-us/hq-hook-linux-arm64": "5.345.148"
117
+ "@indigoai-us/hq-hook-win32-x64": "5.345.150",
118
+ "@indigoai-us/hq-hook-win32-arm64": "5.345.150",
119
+ "@indigoai-us/hq-hook-darwin-x64": "5.345.150",
120
+ "@indigoai-us/hq-hook-darwin-arm64": "5.345.150",
121
+ "@indigoai-us/hq-hook-linux-x64": "5.345.150",
122
+ "@indigoai-us/hq-hook-linux-arm64": "5.345.150"
123
123
  }
124
124
  }