@indigoai-us/hq-cli 5.345.203 → 5.345.204

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.
@@ -17,13 +17,14 @@ export declare const SYNC_CORE_REQUESTS_PER_DAY = 20000;
17
17
  export declare function syncCoreEngineHome(home: string, vaultUid: string): string;
18
18
  export declare function syncCoreUnitId(vaultUid: string): string;
19
19
  export declare function isSyncCoreVaultUid(value: unknown): value is string;
20
- export declare function engineConfigToml(vault: SyncCoreVault, hqRoot: string, phase: SyncCoreVaultPhase): string;
20
+ export declare function engineConfigToml(vault: SyncCoreVault, hqRoot: string, phase: SyncCoreVaultPhase, tokenPath?: string): string;
21
21
  export interface WriteEngineHomeOptions {
22
22
  home: string;
23
23
  hqRoot: string;
24
24
  vault: SyncCoreVault;
25
25
  phase: SyncCoreVaultPhase;
26
26
  tokenFile: string;
27
+ platform?: NodeJS.Platform;
27
28
  }
28
29
  export declare function writeEngineHome(opts: WriteEngineHomeOptions): {
29
30
  engineHome: string;
@@ -11,7 +11,7 @@ export function syncCoreUnitId(vaultUid) {
11
11
  export function isSyncCoreVaultUid(value) {
12
12
  return typeof value === "string" && /^(prs|cmp)_[A-Za-z0-9][A-Za-z0-9_-]*$/.test(value);
13
13
  }
14
- export function engineConfigToml(vault, hqRoot, phase) {
14
+ export function engineConfigToml(vault, hqRoot, phase, tokenPath) {
15
15
  const lines = [
16
16
  "[sync]",
17
17
  'engine = "rust-test"',
@@ -20,6 +20,7 @@ export function engineConfigToml(vault, hqRoot, phase) {
20
20
  `vaults = [${JSON.stringify(vault.uid)}]`,
21
21
  `hq_root = ${JSON.stringify(hqRoot)}`,
22
22
  `requests_per_day = ${SYNC_CORE_REQUESTS_PER_DAY}`,
23
+ ...(tokenPath ? [`token_path = ${JSON.stringify(tokenPath)}`] : []),
23
24
  ];
24
25
  if (vault.kind === "company") {
25
26
  lines.push("[sync.roots]", `${vault.uid} = ${JSON.stringify(`companies/${vault.slug}`)}`);
@@ -52,15 +53,24 @@ function writeIfChanged(file, text) {
52
53
  fs.renameSync(tmp, file);
53
54
  return true;
54
55
  }
56
+ /**
57
+ * The files an engine home links to on macOS and Linux. Windows needs a privilege to create a
58
+ * symlink, so there the config names the token file and the engine reads `menubar.json` and
59
+ * `work-mesh/` from `HQ_STATE_DIR`, which the daemon sets.
60
+ */
61
+ const ENGINE_HOME_LINKS = ["menubar.json", "work-mesh", "cognito-tokens.json"];
55
62
  export function writeEngineHome(opts) {
56
63
  const engineHome = syncCoreEngineHome(opts.home, opts.vault.uid);
57
64
  const hq = path.join(engineHome, ".hq");
58
65
  const root = path.join(hq, "sync-core");
59
66
  fs.mkdirSync(path.join(root, "owned"), { recursive: true, mode: 0o700 });
60
- replaceSymlink(path.join(hq, "menubar.json"), path.join(opts.home, ".hq", "menubar.json"));
61
- replaceSymlink(path.join(hq, "work-mesh"), path.join(opts.home, ".hq", "work-mesh"));
62
- replaceSymlink(path.join(hq, "cognito-tokens.json"), opts.tokenFile);
63
- const configChanged = writeIfChanged(path.join(root, "config.toml"), engineConfigToml(opts.vault, opts.hqRoot, opts.phase));
67
+ const windows = (opts.platform ?? process.platform) === "win32";
68
+ if (!windows) {
69
+ replaceSymlink(path.join(hq, "menubar.json"), path.join(opts.home, ".hq", "menubar.json"));
70
+ replaceSymlink(path.join(hq, "work-mesh"), path.join(opts.home, ".hq", "work-mesh"));
71
+ replaceSymlink(path.join(hq, "cognito-tokens.json"), opts.tokenFile);
72
+ }
73
+ const configChanged = writeIfChanged(path.join(root, "config.toml"), engineConfigToml(opts.vault, opts.hqRoot, opts.phase, windows ? opts.tokenFile : undefined));
64
74
  const ownedPath = path.join(root, "owned", `${opts.vault.uid}.json`);
65
75
  let ownedChanged = false;
66
76
  if (opts.phase === "full") {
@@ -123,8 +133,9 @@ function blocked(plan, blockedReason) {
123
133
  return { ...plan, blockedReason };
124
134
  }
125
135
  export function inspectEngineHome(home, hqRoot, plan, platform) {
126
- if (platform !== "darwin" && platform !== "linux")
127
- return blocked(plan, "the sync engine requires macOS or Linux");
136
+ if (platform !== "darwin" && platform !== "linux" && platform !== "win32") {
137
+ return blocked(plan, "the sync engine requires macOS, Linux or Windows");
138
+ }
128
139
  try {
129
140
  if (!fs.statSync(plan.binaryPath).isFile())
130
141
  return blocked(plan, "the sync engine binary is missing");
@@ -182,7 +193,13 @@ export function inspectEngineHome(home, hqRoot, plan, platform) {
182
193
  else if (fs.existsSync(ownedPath)) {
183
194
  return blocked(plan, `the engine ownership record for ${plan.uid} must not exist while the index warms`);
184
195
  }
185
- for (const link of ["menubar.json", "work-mesh", "cognito-tokens.json"]) {
196
+ if (platform === "win32") {
197
+ if (typeof sync.token_path !== "string" || !path.isAbsolute(sync.token_path)) {
198
+ return blocked(plan, `the engine config for ${plan.uid} must name the token file`);
199
+ }
200
+ return plan;
201
+ }
202
+ for (const link of ENGINE_HOME_LINKS) {
186
203
  try {
187
204
  fs.readlinkSync(path.join(plan.engineHome, ".hq", link));
188
205
  }
@@ -16,6 +16,8 @@ export interface SyncCoreReconcileDeps {
16
16
  ensureBinary: (release: string) => Promise<SyncCoreBinaryInstall>;
17
17
  /** A fixed release (tests). Otherwise readPin decides, then SYNC_CORE_RELEASE. */
18
18
  release?: string;
19
+ platform?: NodeJS.Platform;
20
+ env?: NodeJS.ProcessEnv;
19
21
  /** Reads the server-side engine pin; never throws (see readSyncCorePin). */
20
22
  readPin?: () => Promise<SyncCorePin>;
21
23
  now?: () => Date;
@@ -29,6 +31,6 @@ export interface SyncCoreReconcileResult {
29
31
  kept: string[];
30
32
  warnings: string[];
31
33
  }
32
- export declare function fullModeHold(vault: SyncCoreVault, release: string): string | undefined;
34
+ export declare function fullModeHold(vault: SyncCoreVault, release: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string | undefined;
33
35
  export declare function reconcileSyncCore(deps: SyncCoreReconcileDeps): Promise<SyncCoreReconcileResult>;
34
36
  //# sourceMappingURL=reconcile.d.ts.map
@@ -3,16 +3,21 @@ import * as path from "node:path";
3
3
  import { readCompaniesManifestMap } from "../work-context/repo-remote.js";
4
4
  import { readVaultSyncSwitches, writeVaultSyncSwitches } from "../vault-sync-switches.js";
5
5
  import { clearEngineStatus, engineFirstCycle, isSyncCoreVaultUid, removeEngineOwnership, syncCoreEngineHome, writeEngineHome, } from "./engine-home.js";
6
- import { SYNC_CORE_FULL_RELEASE, SYNC_CORE_RELEASE, compareSyncCoreReleases, fullModeAllowed, installedSyncCoreRelease, syncCoreBinaryPath, } from "./release.js";
6
+ import { SYNC_CORE_FULL_RELEASE, SYNC_CORE_RELEASE, compareSyncCoreReleases, fullModeAllowed, installedSyncCoreRelease, syncCoreBinaryPath, windowsFullRelease, } from "./release.js";
7
7
  import { readSyncCoreSkips } from "./skip.js";
8
8
  import { SYNC_RUST_ENGINE_ROLLOUT_FLAG } from "./flag.js";
9
9
  import { readSyncCoreRolloutState, syncCoreRolloutStatePath, writeSyncCoreRolloutState, } from "./rollout-state.js";
10
10
  function message(error) {
11
11
  return error instanceof Error ? error.message : String(error);
12
12
  }
13
- export function fullModeHold(vault, release) {
14
- if (fullModeAllowed(release))
13
+ export function fullModeHold(vault, release, platform = process.platform, env = process.env) {
14
+ if (fullModeAllowed(release, platform, env))
15
15
  return undefined;
16
+ if (platform === "win32" && fullModeAllowed(release, "linux", env)) {
17
+ const windows = windowsFullRelease(env);
18
+ const needed = windows ? `engine release ${windows} or later` : "an engine release cleared for full sync on Windows";
19
+ return `${vault.kind} vaults on Windows move to the new sync engine with ${needed} (${release} available); staying on the current sync`;
20
+ }
16
21
  const needed = SYNC_CORE_FULL_RELEASE ? `engine release ${SYNC_CORE_FULL_RELEASE} or later` : "an engine release cleared for full sync";
17
22
  return `${vault.kind} vaults move to the new sync engine with ${needed} (${release} installed); staying on the current sync`;
18
23
  }
@@ -65,6 +70,8 @@ function ownedVaultsWithoutState(home, hqRoot) {
65
70
  export async function reconcileSyncCore(deps) {
66
71
  const now = deps.now ?? (() => new Date());
67
72
  const log = deps.log ?? (() => { });
73
+ const platform = deps.platform ?? process.platform;
74
+ const env = deps.env ?? process.env;
68
75
  const warnings = [];
69
76
  let release = deps.release ?? SYNC_CORE_RELEASE;
70
77
  const previous = readSyncCoreRolloutState(deps.home);
@@ -114,8 +121,15 @@ export async function reconcileSyncCore(deps) {
114
121
  catch (error) {
115
122
  warnings.push(message(error));
116
123
  }
117
- let binaryPath = syncCoreBinaryPath(deps.home);
118
- let installedRelease = installedSyncCoreRelease(deps.home);
124
+ let binaryPath = syncCoreBinaryPath(deps.home, platform);
125
+ let installedRelease = installedSyncCoreRelease(deps.home, platform);
126
+ const held = [];
127
+ const best = installedRelease && compareSyncCoreReleases(installedRelease, release) >= 0 ? installedRelease : release;
128
+ if (platform === "win32" && !fullModeAllowed(best, platform, env)) {
129
+ for (const vault of desired)
130
+ held.push({ uid: vault.uid, reason: fullModeHold(vault, best, platform, env) });
131
+ desired.length = 0;
132
+ }
119
133
  if (desired.length > 0) {
120
134
  if (deps.release === undefined && deps.readPin) {
121
135
  const pin = await deps.readPin();
@@ -140,10 +154,9 @@ export async function reconcileSyncCore(deps) {
140
154
  desired.length = 0;
141
155
  }
142
156
  }
143
- const held = [];
144
157
  const engineRelease = installedRelease ?? release;
145
158
  for (let i = desired.length - 1; i >= 0; i -= 1) {
146
- const reason = fullModeHold(desired[i], engineRelease);
159
+ const reason = fullModeHold(desired[i], engineRelease, platform, env);
147
160
  if (!reason)
148
161
  continue;
149
162
  held.unshift({ uid: desired[i].uid, reason });
@@ -162,7 +175,7 @@ export async function reconcileSyncCore(deps) {
162
175
  const engineHome = syncCoreEngineHome(deps.home, vault.uid);
163
176
  if (!before)
164
177
  clearEngineStatus(deps.home, vault.uid);
165
- writeEngineHome({ home: deps.home, hqRoot: deps.hqRoot, vault, phase: "full", tokenFile: deps.tokenFile });
178
+ writeEngineHome({ home: deps.home, hqRoot: deps.hqRoot, vault, phase: "full", tokenFile: deps.tokenFile, platform });
166
179
  const wasFull = before?.phase === "full";
167
180
  const alreadyOff = vault.kind === "personal"
168
181
  ? switchesBefore.personalOff
@@ -1,7 +1,15 @@
1
1
  export declare const SYNC_CORE_RELEASE = "v0.1.23";
2
2
  export declare const SYNC_CORE_FULL_RELEASE: string | null;
3
+ /**
4
+ * The first engine release whose Windows build runs full sync. Until it is set, Windows vaults
5
+ * stay on the current sync and no Windows engine is downloaded. `HQ_SYNC_CORE_WINDOWS_FULL_RELEASE`
6
+ * overrides it on one machine, for testing a build before it is released.
7
+ */
8
+ export declare const SYNC_CORE_WINDOWS_FULL_RELEASE: string | null;
9
+ export declare const SYNC_CORE_WINDOWS_FULL_RELEASE_ENV = "HQ_SYNC_CORE_WINDOWS_FULL_RELEASE";
3
10
  export declare function compareSyncCoreReleases(a: string, b: string): number;
4
- export declare function fullModeAllowed(release: string): boolean;
11
+ export declare function windowsFullRelease(env?: NodeJS.ProcessEnv): string | null;
12
+ export declare function fullModeAllowed(release: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): boolean;
5
13
  export declare const SYNC_CORE_DOWNLOAD_BASE = "https://indigoai-public.s3.amazonaws.com/hq-sync-core";
6
14
  export declare const SYNC_CORE_DOWNLOAD_BASE_ENV = "HQ_SYNC_CORE_DOWNLOAD_BASE";
7
15
  /** The server-side engine pin, published next to the release folders on the download base. */
@@ -18,8 +26,8 @@ export interface SyncCorePin {
18
26
  * The engine release to install, read from `<download base>/pin.json`
19
27
  * (`{"release":"v0.1.24"}`), so an engine release reaches machines without an
20
28
  * hq-cli release. Falls back to SYNC_CORE_RELEASE when the file is missing,
21
- * unreadable or malformed. Never throws. Windows stays unsupported: the pin
22
- * only picks a version, and syncCoreAssetName has no Windows build.
29
+ * unreadable or malformed. Never throws. The pin only picks a version: on
30
+ * Windows the release gate (fullModeAllowed) still decides whether it installs.
23
31
  */
24
32
  export declare function readSyncCorePin(opts?: {
25
33
  env?: NodeJS.ProcessEnv;
@@ -27,13 +35,14 @@ export declare function readSyncCorePin(opts?: {
27
35
  fetch?: typeof fetch;
28
36
  timeoutMs?: number;
29
37
  }): Promise<SyncCorePin>;
30
- export declare function syncCoreBinaryPath(home?: string): string;
38
+ export declare function syncCoreBinaryName(platform?: NodeJS.Platform): string;
39
+ export declare function syncCoreBinaryPath(home?: string, platform?: NodeJS.Platform): string;
31
40
  export declare function syncCoreReleaseMarkerPath(home?: string): string;
32
41
  export declare function syncCoreAssetName(release: string, platform: NodeJS.Platform, arch: string): string | null;
33
42
  export declare function syncCoreDownloadBase(env?: NodeJS.ProcessEnv): string;
34
43
  export declare function parseSha256Sums(text: string): Map<string, string>;
35
44
  export declare function syncCoreBinaryVersion(binaryPath: string): string | null;
36
- export declare function installedSyncCoreRelease(home: string): string | null;
45
+ export declare function installedSyncCoreRelease(home: string, platform?: NodeJS.Platform): string | null;
37
46
  export interface EnsureSyncCoreBinaryOptions {
38
47
  home: string;
39
48
  platform: NodeJS.Platform;
@@ -5,6 +5,13 @@ import * as path from "node:path";
5
5
  import { execFileSync } from "node:child_process";
6
6
  export const SYNC_CORE_RELEASE = "v0.1.23";
7
7
  export const SYNC_CORE_FULL_RELEASE = "v0.1.23";
8
+ /**
9
+ * The first engine release whose Windows build runs full sync. Until it is set, Windows vaults
10
+ * stay on the current sync and no Windows engine is downloaded. `HQ_SYNC_CORE_WINDOWS_FULL_RELEASE`
11
+ * overrides it on one machine, for testing a build before it is released.
12
+ */
13
+ export const SYNC_CORE_WINDOWS_FULL_RELEASE = null;
14
+ export const SYNC_CORE_WINDOWS_FULL_RELEASE_ENV = "HQ_SYNC_CORE_WINDOWS_FULL_RELEASE";
8
15
  export function compareSyncCoreReleases(a, b) {
9
16
  const parse = (release) => release.replace(/^v/, "").split(".").map((part) => Number.parseInt(part, 10) || 0);
10
17
  const [x, y] = [parse(a), parse(b)];
@@ -15,8 +22,17 @@ export function compareSyncCoreReleases(a, b) {
15
22
  }
16
23
  return 0;
17
24
  }
18
- export function fullModeAllowed(release) {
19
- return SYNC_CORE_FULL_RELEASE !== null && compareSyncCoreReleases(release, SYNC_CORE_FULL_RELEASE) >= 0;
25
+ export function windowsFullRelease(env = process.env) {
26
+ const override = env[SYNC_CORE_WINDOWS_FULL_RELEASE_ENV]?.trim();
27
+ return override && /^v?\d+\.\d+\.\d+$/.test(override) ? override : SYNC_CORE_WINDOWS_FULL_RELEASE;
28
+ }
29
+ export function fullModeAllowed(release, platform = process.platform, env = process.env) {
30
+ if (SYNC_CORE_FULL_RELEASE === null || compareSyncCoreReleases(release, SYNC_CORE_FULL_RELEASE) < 0)
31
+ return false;
32
+ if (platform !== "win32")
33
+ return true;
34
+ const windows = windowsFullRelease(env);
35
+ return windows !== null && compareSyncCoreReleases(release, windows) >= 0;
20
36
  }
21
37
  export const SYNC_CORE_DOWNLOAD_BASE = "https://indigoai-public.s3.amazonaws.com/hq-sync-core";
22
38
  export const SYNC_CORE_DOWNLOAD_BASE_ENV = "HQ_SYNC_CORE_DOWNLOAD_BASE";
@@ -29,8 +45,8 @@ const RELEASE_PATTERN = /^v\d+\.\d+\.\d+$/;
29
45
  * The engine release to install, read from `<download base>/pin.json`
30
46
  * (`{"release":"v0.1.24"}`), so an engine release reaches machines without an
31
47
  * hq-cli release. Falls back to SYNC_CORE_RELEASE when the file is missing,
32
- * unreadable or malformed. Never throws. Windows stays unsupported: the pin
33
- * only picks a version, and syncCoreAssetName has no Windows build.
48
+ * unreadable or malformed. Never throws. The pin only picks a version: on
49
+ * Windows the release gate (fullModeAllowed) still decides whether it installs.
34
50
  */
35
51
  export async function readSyncCorePin(opts = {}) {
36
52
  const builtIn = (warning) => ({ release: SYNC_CORE_RELEASE, source: "built-in", ...(warning ? { warning } : {}) });
@@ -60,8 +76,11 @@ export async function readSyncCorePin(opts = {}) {
60
76
  }
61
77
  return { release, source: "server" };
62
78
  }
63
- export function syncCoreBinaryPath(home = os.homedir()) {
64
- return path.join(home, ".hq", "bin", "hq-syncd");
79
+ export function syncCoreBinaryName(platform = process.platform) {
80
+ return platform === "win32" ? "hq-syncd.exe" : "hq-syncd";
81
+ }
82
+ export function syncCoreBinaryPath(home = os.homedir(), platform = process.platform) {
83
+ return path.join(home, ".hq", "bin", syncCoreBinaryName(platform));
65
84
  }
66
85
  export function syncCoreReleaseMarkerPath(home = os.homedir()) {
67
86
  return path.join(home, ".hq", "bin", "hq-syncd.release");
@@ -73,6 +92,10 @@ export function syncCoreAssetName(release, platform, arch) {
73
92
  return `hq-sync-core-${release}-linux-x64.tar.gz`;
74
93
  if (platform === "linux" && arch === "arm64")
75
94
  return `hq-sync-core-${release}-linux-arm64.tar.gz`;
95
+ if (platform === "win32" && arch === "x64")
96
+ return `hq-sync-core-${release}-windows-x64.zip`;
97
+ if (platform === "win32" && arch === "arm64")
98
+ return `hq-sync-core-${release}-windows-arm64.zip`;
76
99
  return null;
77
100
  }
78
101
  export function syncCoreDownloadBase(env = process.env) {
@@ -98,9 +121,9 @@ export function syncCoreBinaryVersion(binaryPath) {
98
121
  return null;
99
122
  }
100
123
  }
101
- export function installedSyncCoreRelease(home) {
124
+ export function installedSyncCoreRelease(home, platform = process.platform) {
102
125
  try {
103
- const binary = syncCoreBinaryPath(home);
126
+ const binary = syncCoreBinaryPath(home, platform);
104
127
  if (!fs.statSync(binary).isFile())
105
128
  return null;
106
129
  fs.accessSync(binary, fs.constants.X_OK);
@@ -130,6 +153,24 @@ function findFile(dir, name) {
130
153
  }
131
154
  return null;
132
155
  }
156
+ /**
157
+ * Windows cannot replace an executable that is running, but it can rename one. The old engine
158
+ * keeps running from `<binary>.old` until its unit restarts; the copy left by the previous
159
+ * update is removed first when nothing runs from it any more.
160
+ */
161
+ function moveRunningBinaryAside(binaryPath) {
162
+ if (!fs.existsSync(binaryPath))
163
+ return;
164
+ const aside = `${binaryPath}.old`;
165
+ try {
166
+ fs.rmSync(aside, { force: true });
167
+ }
168
+ catch {
169
+ // still running from the previous update; that copy is removed on a later one
170
+ }
171
+ const target = fs.existsSync(aside) ? `${binaryPath}.${process.pid}.old` : aside;
172
+ fs.renameSync(binaryPath, target);
173
+ }
133
174
  async function download(fetcher, url) {
134
175
  let response;
135
176
  try {
@@ -144,8 +185,8 @@ async function download(fetcher, url) {
144
185
  }
145
186
  export async function ensureSyncCoreBinary(opts) {
146
187
  const release = opts.release ?? SYNC_CORE_RELEASE;
147
- const binaryPath = syncCoreBinaryPath(opts.home);
148
- const installedRelease = installedSyncCoreRelease(opts.home);
188
+ const binaryPath = syncCoreBinaryPath(opts.home, opts.platform);
189
+ const installedRelease = installedSyncCoreRelease(opts.home, opts.platform);
149
190
  if (installedRelease && compareSyncCoreReleases(installedRelease, release) >= 0 && fs.existsSync(binaryPath)) {
150
191
  const marker = syncCoreReleaseMarkerPath(opts.home);
151
192
  let current = "";
@@ -186,13 +227,16 @@ export async function ensureSyncCoreBinary(opts) {
186
227
  fs.writeFileSync(archive, bytes, { mode: 0o600 });
187
228
  const extracted = path.join(staging, "extracted");
188
229
  fs.mkdirSync(extracted, { mode: 0o700 });
189
- run("tar", ["-xzf", archive, "-C", extracted]);
190
- const unpacked = findFile(extracted, "hq-syncd");
230
+ run("tar", [asset.endsWith(".zip") ? "-xf" : "-xzf", archive, "-C", extracted]);
231
+ const name = syncCoreBinaryName(opts.platform);
232
+ const unpacked = findFile(extracted, name);
191
233
  if (!unpacked)
192
- throw new SyncCoreReleaseError(`${asset} does not contain hq-syncd`);
193
- const prepared = path.join(staging, "hq-syncd");
234
+ throw new SyncCoreReleaseError(`${asset} does not contain ${name}`);
235
+ const prepared = path.join(staging, name);
194
236
  fs.copyFileSync(unpacked, prepared);
195
237
  fs.chmodSync(prepared, 0o700);
238
+ if (opts.platform === "win32")
239
+ moveRunningBinaryAside(binaryPath);
196
240
  fs.renameSync(prepared, binaryPath);
197
241
  const marker = syncCoreReleaseMarkerPath(opts.home);
198
242
  fs.writeFileSync(`${marker}.tmp`, `${release}\n`, { mode: 0o600 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.345.203",
3
+ "version": "5.345.204",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -117,11 +117,11 @@
117
117
  "*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}": "eslint --cache --no-error-on-unmatched-pattern"
118
118
  },
119
119
  "optionalDependencies": {
120
- "@indigoai-us/hq-hook-win32-x64": "5.345.203",
121
- "@indigoai-us/hq-hook-win32-arm64": "5.345.203",
122
- "@indigoai-us/hq-hook-darwin-x64": "5.345.203",
123
- "@indigoai-us/hq-hook-darwin-arm64": "5.345.203",
124
- "@indigoai-us/hq-hook-linux-x64": "5.345.203",
125
- "@indigoai-us/hq-hook-linux-arm64": "5.345.203"
120
+ "@indigoai-us/hq-hook-win32-x64": "5.345.204",
121
+ "@indigoai-us/hq-hook-win32-arm64": "5.345.204",
122
+ "@indigoai-us/hq-hook-darwin-x64": "5.345.204",
123
+ "@indigoai-us/hq-hook-darwin-arm64": "5.345.204",
124
+ "@indigoai-us/hq-hook-linux-x64": "5.345.204",
125
+ "@indigoai-us/hq-hook-linux-arm64": "5.345.204"
126
126
  }
127
127
  }