@indigoai-us/hq-cli 5.345.74 → 5.345.75

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,18 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.345.75] — 2026-10-10
6
+
7
+ - Native delegate manifest updates now use mode 0600 on POSIX, matching the
8
+ shell commands and preventing the manifest from becoming readable by other
9
+ local users.
10
+ - Lane lifecycle delivery, worker continuity, status-row fields, and operator-requested orphan stopping now stay enabled when their hq-flags registry rows are missing or unavailable.
11
+ - `hq uninstall --global --runtime codex` is now idempotent: on a machine with
12
+ no global Codex installation it reports that there is nothing to remove and
13
+ exits successfully.
14
+ - Delegate send now stops before DM delivery and reports the shell-compatible
15
+ error when saving the `sending` state fails.
16
+
5
17
  ## [5.345.74] — 2026-10-10
6
18
 
7
19
  - Lane envelope repair prompts now identify parser locations and schema fields,
@@ -59,9 +59,13 @@ case "$STATUS" in
59
59
  esac
60
60
 
61
61
  record_pickup() { # <kind> <detail>
62
- jq --arg now "$NOW" --arg k "$1" --arg d "$2" \
62
+ local TMP_MANIFEST
63
+ TMP_MANIFEST="$(mktemp "${MANIFEST}.tmp.XXXXXX")" || exit 1
64
+ if ! jq --arg now "$NOW" --arg k "$1" --arg d "$2" \
63
65
  '.status = "picked-up" | .pickedUpAt = $now | .pickup = {kind: $k, detail: $d, recordedAt: $now}' \
64
- "$MANIFEST" > "$MANIFEST.tmp" && mv "$MANIFEST.tmp" "$MANIFEST"
66
+ "$MANIFEST" > "$TMP_MANIFEST" || ! mv "$TMP_MANIFEST" "$MANIFEST"; then
67
+ rm -f "$TMP_MANIFEST"
68
+ fi
65
69
  echo "hq-delegate-pickup: $NAME picked up the delegation ($1) — status advanced to 'picked-up'"
66
70
  exit 0
67
71
  }
@@ -93,7 +97,10 @@ if [ "$age_h" -lt "$WINDOW" ]; then
93
97
  exit 6
94
98
  fi
95
99
  reason="no pickup evidence from $NAME within ${WINDOW}h of send (${SENT_AT:-unknown}): no acknowledgement, no commit by $TO on ${BRANCH:-the branch}"
96
- jq --arg now "$NOW" --arg r "$reason" '.status = "failed" | .failedAt = $now | .failure = {reason: $r, recordedAt: $now}' \
97
- "$MANIFEST" > "$MANIFEST.tmp" && mv "$MANIFEST.tmp" "$MANIFEST"
100
+ TMP_MANIFEST="$(mktemp "${MANIFEST}.tmp.XXXXXX")" || exit 1
101
+ if ! jq --arg now "$NOW" --arg r "$reason" '.status = "failed" | .failedAt = $now | .failure = {reason: $r, recordedAt: $now}' \
102
+ "$MANIFEST" > "$TMP_MANIFEST" || ! mv "$TMP_MANIFEST" "$MANIFEST"; then
103
+ rm -f "$TMP_MANIFEST"
104
+ fi
98
105
  echo "hq-delegate-pickup: FAILED — $reason. Re-send with a direct ask, or hand it to someone else." >&2
99
106
  exit 5
@@ -174,6 +174,23 @@ function parseFlags(args, allowed) {
174
174
  }
175
175
  function usage(name) { return USAGE[name] ?? ""; }
176
176
  function usageFailure(name) { err(usage(name)); return 1; }
177
+ function grantHasDanglingManifestFlag(args) {
178
+ for (let i = 0; i < args.length;) {
179
+ const key = args[i] ?? "";
180
+ if (key === "--yes") {
181
+ i += 1;
182
+ continue;
183
+ }
184
+ if (key === "--manifest") {
185
+ if (i + 1 >= args.length)
186
+ return true;
187
+ i += 2;
188
+ continue;
189
+ }
190
+ return false;
191
+ }
192
+ return false;
193
+ }
177
194
  function bashPath(value) {
178
195
  if (process.platform !== "win32")
179
196
  return value;
@@ -205,6 +222,10 @@ function runBundle(args, context, onMalformedWhoami) {
205
222
  const root = context.root ?? context.cwd;
206
223
  if (args[0] !== "build")
207
224
  return usageFailure("bundle");
225
+ // The shell uses `shift 2` for these options. With no value at end of argv,
226
+ // Bash exits nonzero before it reaches the required-field diagnostics.
227
+ if (["--company", "--project", "--to", "--to-kind", "--to-name", "--mode"].includes(args.at(-1) ?? ""))
228
+ return 1;
208
229
  const parsed = parseFlags(args.slice(1), ["--company", "--project", "--to", "--to-kind", "--to-name", "--mode", "--dry-run"]);
209
230
  if (parsed.help) {
210
231
  out(usage("bundle"));
@@ -326,7 +347,7 @@ function runBundle(args, context, onMalformedWhoami) {
326
347
  const next = stories.filter((story) => !isRecord(story) || story.passes !== true)
327
348
  .sort((a, b) => Number(getPath(a, "priority", 0)) - Number(getPath(b, "priority", 0))).slice(0, 3);
328
349
  const doneList = done.map((story) => `- ${text(getPath(story, "id"))}: ${text(getPath(story, "title"))}`).join("\n");
329
- const nextList = next.map((story) => `### ${text(getPath(story, "id"))}: ${text(getPath(story, "title"))}\n\n${text(getPath(story, "description"))}\n`).join("\n");
350
+ const nextList = next.map((story) => `### ${text(getPath(story, "id"))}: ${text(getPath(story, "title"))}\n\n${text(getPath(story, "description"))}\n`).join("\n").replace(/\n+$/, "");
330
351
  const questions = list(getPath(prd, "metadata.openQuestions", [])).map((entry) => `- ${text(entry)}`).join("\n");
331
352
  const traps = [
332
353
  ...list(getPath(prd, "metadata.securityNotes", [])),
@@ -410,6 +431,10 @@ const ACL_FILTER = `
410
431
  (.direct | type == "array") and (.exists | type == "boolean")
411
432
  `;
412
433
  function runGrant(args, context) {
434
+ // The shell companion's `shift 2` runs under `set -e`; a final bare
435
+ // --manifest exits 1 without diagnostics. Preserve that observable contract.
436
+ if (grantHasDanglingManifestFlag(args))
437
+ return 1;
413
438
  const parsed = parseFlags(args, ["--manifest", "--yes"]);
414
439
  if (parsed.help) {
415
440
  out(usage("grant"));
@@ -618,10 +643,14 @@ function runGrant(args, context) {
618
643
  out(`hq-delegate-grant: all ${prefixes.length} grants verified — manifest status advanced to 'granted'\n`);
619
644
  return 0;
620
645
  }
621
- function atomicCopy(source, target) {
646
+ function atomicCopy(source, target, mode) {
622
647
  const temporary = `${target}.tmp.${process.pid}.${Math.random().toString(16).slice(2)}`;
623
648
  try {
624
- fs.copyFileSync(source, temporary);
649
+ const contents = fs.readFileSync(source);
650
+ if (mode === undefined)
651
+ fs.writeFileSync(temporary, contents, { flag: "wx" });
652
+ else
653
+ fs.writeFileSync(temporary, contents, { flag: "wx", mode });
625
654
  moveFile(temporary, target);
626
655
  }
627
656
  catch (error) {
@@ -745,9 +774,9 @@ function runPublish(args, context) {
745
774
  if (shareSession.test(fs.readFileSync(stagedManifest, "utf8")) || shareSession.test(fs.readFileSync(stagedBrief, "utf8")))
746
775
  return fail("publish", "share-session capability in dossier; nothing published");
747
776
  fs.mkdirSync(dest, { recursive: true });
748
- atomicCopy(stagedBrief, path.join(dest, "BRIEF.md"));
749
- atomicCopy(stagedManifest, path.join(dest, "manifest.json"));
750
- atomicCopy(stagedManifest, manifestPath);
777
+ atomicCopy(stagedBrief, path.join(dest, "BRIEF.md"), 0o600);
778
+ atomicCopy(stagedManifest, path.join(dest, "manifest.json"), 0o600);
779
+ atomicCopy(stagedManifest, manifestPath, 0o600);
751
780
  const push = runHq(["sync", "push", `${relative}/`, "--company", company, "--on-conflict", "keep"], context, "inherit");
752
781
  if (push.code !== 0)
753
782
  return fail("publish", "final dossier push failed; resume publication");
@@ -775,7 +804,7 @@ function runPublish(args, context) {
775
804
  const publication = { verifiedAt: currentTime(), manifestPath: `${relative}/delegation/${id}/manifest.json`, files: receipts };
776
805
  const updated = { ...canonical, publication, recipientAccess: "unconfirmed" };
777
806
  fs.writeFileSync(stagedManifest, jsonText(updated));
778
- atomicCopy(stagedManifest, manifestPath);
807
+ atomicCopy(stagedManifest, manifestPath, 0o600);
779
808
  out("hq-delegate-publish: canonical dossier bytes verified as sender; recipient access unconfirmed\n");
780
809
  return 0;
781
810
  }
@@ -794,6 +823,10 @@ function sortedJson(value) {
794
823
  return serializeJqJson(sort(value), "compact").replace(/\n+$/, "");
795
824
  }
796
825
  function runSend(args, context) {
826
+ // The shell shifts two arguments for value options. Under `set -e`, a
827
+ // trailing option without its value exits 1 before printing diagnostics.
828
+ if (["--manifest", "--headline", "--note"].includes(args.at(-1) ?? ""))
829
+ return 1;
797
830
  const parsed = parseFlags(args, ["--manifest", "--send", "--headline", "--note"]);
798
831
  if (parsed.help) {
799
832
  out(usage("send"));
@@ -884,7 +917,7 @@ function runSend(args, context) {
884
917
  const access = jqRawPath(manifest, "repo.accessNote");
885
918
  const branchCheck = branch ? subprocess("git", ["check-ref-format", "--branch", branch], context.cwd, { stdout: "ignore", stderr: "ignore" }) : { code: 1 };
886
919
  if (branch && branchCheck.code === 0 && sha) {
887
- repoSection = `## Get the code\n\nThe work lives on branch \`${branch}\` (base: \`${base}\`) at \`${sha}\`.\n\n\`\`\`bash\n# From your HQ root; clone first if the repo is not present${remote ? ` (remote: ${remote})` : ""}:\ngit -C ${quoteBash(repoPath)} fetch origin\ngit -C ${quoteBash(repoPath)} switch -- ${quoteBash(branch)}\n\`\`\`${access ? `\n\n> ${access}` : ""}`;
920
+ repoSection = `## Get the code\n\nThe work lives on branch \`${branch}\` (base: \`${base}\`) at \`${sha}\`.\n\n\`\`\`bash\n# From your HQ root; clone first if the repo is not present${remote ? ` (remote: ${remote})` : ""}:\ngit -C ${quoteBash(repoPath)} fetch origin\ngit -C ${quoteBash(repoPath)} switch -- ${quoteBash(branch)}\n\`\`\`${access ? `\n\n> ${access}` : "\n"}`;
888
921
  }
889
922
  }
890
923
  const secretNames = list(getPath(manifest, "secrets", [])).map((entry) => text(entry)).join(",");
@@ -906,7 +939,7 @@ function runSend(args, context) {
906
939
  if (repoSection)
907
940
  body += `${repoSection}\n\n`;
908
941
  if (secretsSection)
909
- body += `${secretsSection}\n`;
942
+ body += `${secretsSection}\n\n`;
910
943
  if (nextSteps)
911
944
  body += `## Your next three steps\n\n${nextSteps}\n\n`;
912
945
  body += `## If something is off\n\nThe manifest and BRIEF.md are published under \`delegation/${delegationId}/\` within \`companies/${company}/projects/${project}/\`. If a pull fails or a path looks empty, report it to ${from}.\n`;
@@ -956,7 +989,12 @@ function runSend(args, context) {
956
989
  if (checksum(brief) !== checksum(path.join(path.dirname(publishedManifestPath), "BRIEF.md")))
957
990
  return fail("send", "brief changed since publication; run verification again");
958
991
  manifest.status = "sending";
959
- writeJsonAtomically(manifestPath, manifest, true);
992
+ try {
993
+ writeJsonAtomically(manifestPath, manifest, true, context.atomicWriteFileSystem);
994
+ }
995
+ catch {
996
+ return fail("send", "could not persist sending state; no DM attempted");
997
+ }
960
998
  const dm = runHq(["dm", principal, headline, "--prompt-file", prompt, "--details-file", brief], context);
961
999
  if (dm.code !== 0)
962
1000
  return fail("send", "hq dm delivery outcome is uncertain; status is sending, inspect DM history before retrying");
@@ -994,6 +1032,10 @@ function captureRun(run) {
994
1032
  }
995
1033
  }
996
1034
  function runVerify(args, context) {
1035
+ // The shell shifts a value-taking option and its value under `set -e`.
1036
+ // A trailing option therefore exits 1 before any diagnostic is printed.
1037
+ if (["--manifest", "--company", "--project", "--to", "--mode"].includes(args.at(-1) ?? ""))
1038
+ return 1;
997
1039
  const parsed = parseFlags(args, ["--manifest", "--dry-run", "--company", "--project", "--to", "--mode"]);
998
1040
  if (parsed.help) {
999
1041
  out(usage("verify"));
@@ -1051,7 +1093,7 @@ function runVerify(args, context) {
1051
1093
  out(` Recipient: ${recipient}\n Mode: ${mode}\n Company: ${company}\n Project: ${project}\n\n`);
1052
1094
  out(" Vault grants that would be written:\n");
1053
1095
  for (const entry of list(getPath(manifest, "vaultPrefixes", [])))
1054
- out(` ${jqRawPath(entry, "permission")}\t on ${jqRawPath(entry, "prefix")}\t(${jqRawPath(entry, "reason")})\n`);
1096
+ out(` ${jqRawPath(entry, "permission")}\ton ${jqRawPath(entry, "prefix")}\t(${jqRawPath(entry, "reason")})\n`);
1055
1097
  out(`\n Secret names that would be granted (read): ${secretNames}\n\n`);
1056
1098
  const repoValue = getPath(manifest, "repo");
1057
1099
  if (repoValue !== null && repoValue !== undefined)
@@ -1,11 +1,14 @@
1
1
  /** Native implementations of the five `hq core delegate` shell companions. */
2
+ import * as fs from "node:fs";
2
3
  import { Command } from "commander";
3
4
  import { type SpawnPlan } from "../utils/windows-spawn.js";
4
5
  export declare const CORE_NATIVE_DELEGATE_FLAG = "core-native-delegate";
5
6
  export type DelegateContext = {
6
7
  cwd: string;
7
8
  root?: string;
9
+ atomicWriteFileSystem?: DelegateAtomicWriteFileSystem;
8
10
  };
11
+ export type DelegateAtomicWriteFileSystem = Pick<typeof fs, "openSync" | "writeFileSync" | "closeSync" | "renameSync" | "copyFileSync" | "unlinkSync" | "rmSync">;
9
12
  type CommandResult = {
10
13
  code: number;
11
14
  stdout?: string;
@@ -38,8 +41,8 @@ export declare function rawJsonValue(value: unknown): string;
38
41
  export declare function jqRawPath(value: unknown, dottedPath: string, fallback?: unknown): string;
39
42
  export declare function jqRawPaths(value: unknown, dottedPaths: string[], fallback?: unknown): string;
40
43
  export declare function requireRecord(value: unknown, property: string): JsonRecord;
41
- export declare function moveFile(source: string, target: string): void;
42
- export declare function writeJsonAtomically(target: string, value: unknown, siblingTemp?: boolean): void;
44
+ export declare function moveFile(source: string, target: string, fileSystem?: Pick<DelegateAtomicWriteFileSystem, "renameSync" | "copyFileSync" | "unlinkSync">): void;
45
+ export declare function writeJsonAtomically(target: string, value: unknown, siblingTemp?: boolean, fileSystem?: DelegateAtomicWriteFileSystem): void;
43
46
  export declare function delegateDiagnosticPath(argument: string): string;
44
47
  export declare function scanSecretFiles(file: string): string[] | undefined;
45
48
  /** Fast-entry adapter; family gating and shell fallback happen before import. */
@@ -1,5 +1,6 @@
1
1
  /** Native implementations of the five `hq core delegate` shell companions. */
2
2
  import { spawnSync } from "node:child_process";
3
+ import { randomBytes } from "node:crypto";
3
4
  import * as fs from "node:fs";
4
5
  import * as os from "node:os";
5
6
  import * as path from "node:path";
@@ -174,25 +175,59 @@ export function requireRecord(value, property) {
174
175
  throw new TypeError(`Cannot update non-object field ${property}`);
175
176
  return result;
176
177
  }
177
- export function moveFile(source, target) {
178
+ export function moveFile(source, target, fileSystem = fs) {
178
179
  try {
179
- fs.renameSync(source, target);
180
+ fileSystem.renameSync(source, target);
180
181
  }
181
182
  catch (error) {
182
183
  if (error.code !== "EXDEV")
183
184
  throw error;
184
185
  // The shell companion uses `mv`, which copies across filesystem boundaries.
185
- fs.copyFileSync(source, target);
186
- fs.unlinkSync(source);
186
+ fileSystem.copyFileSync(source, target);
187
+ fileSystem.unlinkSync(source);
187
188
  }
188
189
  }
189
- export function writeJsonAtomically(target, value, siblingTemp = false) {
190
+ export function writeJsonAtomically(target, value, siblingTemp = false, fileSystem = fs) {
190
191
  const serialized = serializeJqJson(value, "pretty");
191
192
  // Native delegate JSON writers use LF on every platform.
192
193
  if (siblingTemp) {
193
- const temporary = `${target}.tmp`;
194
- fs.writeFileSync(temporary, serialized);
195
- moveFile(temporary, target);
194
+ const temporary = `${target}.tmp.${randomBytes(6).toString("hex")}`;
195
+ let fd;
196
+ let descriptorOpen = false;
197
+ let temporaryCreated = false;
198
+ try {
199
+ fd = fileSystem.openSync(temporary, "wx", 0o600);
200
+ descriptorOpen = true;
201
+ temporaryCreated = true;
202
+ fileSystem.writeFileSync(fd, serialized);
203
+ fileSystem.closeSync(fd);
204
+ descriptorOpen = false;
205
+ moveFile(temporary, target, fileSystem);
206
+ }
207
+ catch (error) {
208
+ const failures = [error];
209
+ if (descriptorOpen && fd !== undefined) {
210
+ try {
211
+ fileSystem.closeSync(fd);
212
+ descriptorOpen = false;
213
+ }
214
+ catch (closeError) {
215
+ failures.push(closeError);
216
+ }
217
+ }
218
+ if (temporaryCreated) {
219
+ try {
220
+ fileSystem.rmSync(temporary, { force: true });
221
+ }
222
+ catch (cleanupError) {
223
+ failures.push(cleanupError);
224
+ }
225
+ }
226
+ if (failures.length > 1) {
227
+ throw new AggregateError(failures, "Failed to write and clean up delegate manifest temporary file");
228
+ }
229
+ throw error;
230
+ }
196
231
  return;
197
232
  }
198
233
  const temporaryDir = fs.mkdtempSync(path.join(os.tmpdir(), "hq-delegate-"));
@@ -919,8 +919,10 @@ export function uninstallGlobalCodex(opts = {}) {
919
919
  const hqPointer = claudeTargets(home).hqPointer;
920
920
  const state = readCodexState(t);
921
921
  const hqRoot = state?.hqRoot ?? opts.hqRoot ?? readOrNull(hqPointer)?.trim();
922
- if (!hqRoot)
923
- throw new Error('No HQ global install found (no install state and no ~/.hq/root).');
922
+ if (!hqRoot) {
923
+ log('No HQ global Codex install found; nothing to remove.');
924
+ return [];
925
+ }
924
926
  const regFile = opts.registryFile ?? registryFile(registryDir(home, env));
925
927
  const claudeStillInstalled = fs.existsSync(claudeTargets(home).stateFile);
926
928
  const providerBin = path.join(home, '.hq', 'bin');
@@ -158,5 +158,6 @@ export declare function pickupFailureUpdater(reasonRaw: string, details: Record<
158
158
  export declare function applyOutpostAccountPickup(hqRoot: string, laneId: string, modelDeps?: KnownModelsDeps): LaneRecord;
159
159
  export declare function cancelPendingQuestionsForLane(hqRoot: string, laneId: string, nowIso: string, operatorReason?: string): QuestionRecord[];
160
160
  export declare function stopCommittedState(state: LaneRecord["state"]): "cancelled" | "killed";
161
+ export declare function readLaneReapStopEnabled(hqRoot: string, lane: LaneRecord, env: NodeJS.ProcessEnv): Promise<boolean>;
161
162
  export declare function registerLanesCommand(parent: Command, deps?: LanesCommandDeps): Command;
162
163
  //# sourceMappingURL=lanes.d.ts.map
@@ -3392,7 +3392,7 @@ async function runCreate(ctx, opts) {
3392
3392
  const provider = explicitProvider ??
3393
3393
  profile?.meta.provider ??
3394
3394
  parseLaneProvider("codex");
3395
- const continuityEnabled = opts.worker !== undefined && await readLanesRegistryFlagFailOpen(LANE_WORKER_CONTINUITY_FLAG, { company: company ?? meshCompany, env: ctx.env });
3395
+ const continuityEnabled = opts.worker !== undefined && await readLanesRegistryFlagFailOpen(LANE_WORKER_CONTINUITY_FLAG, { company: company ?? meshCompany, env: ctx.env, defaultValue: true });
3396
3396
  let workerContinuity = continuityEnabled
3397
3397
  ? findWorkerContinuityLane(loadAllLanes(hqRoot), {
3398
3398
  senior,
@@ -5456,6 +5456,7 @@ async function laneStatusFieldsForCommand(ctx, hqRoot, lane, now) {
5456
5456
  enabled = await readLanesRegistryFlagFailOpen(LANE_STATUS_ROW_FIELDS_FLAG, {
5457
5457
  ...(resolved ? { company: resolved } : {}),
5458
5458
  env: ctx.env,
5459
+ defaultValue: true,
5459
5460
  });
5460
5461
  }
5461
5462
  catch (err) {
@@ -9365,6 +9366,16 @@ function attachJsonNoop(cmd) {
9365
9366
  for (const child of cmd.commands)
9366
9367
  attachJsonNoop(child);
9367
9368
  }
9369
+ export async function readLaneReapStopEnabled(hqRoot, lane, env) {
9370
+ const resolution = resolveLaneCompany(hqRoot, lane);
9371
+ const company = resolution.company ?? undefined;
9372
+ return readLanesRegistryFlagFailOpen(LANE_REAP_STOP_FLAG, {
9373
+ company,
9374
+ ...(company ? { companyUidSource: laneCompanyUidSource(resolution.source) } : {}),
9375
+ env,
9376
+ defaultValue: true,
9377
+ });
9378
+ }
9368
9379
  export function registerLanesCommand(parent, deps = {}) {
9369
9380
  const ctx = resolveDeps(deps);
9370
9381
  const storyHandlers = createLaneStoryHandlers({
@@ -9566,15 +9577,7 @@ export function registerLanesCommand(parent, deps = {}) {
9566
9577
  presenceConnected: ctx.presenceConnected ?? false,
9567
9578
  deps: ctx.livenessDeps,
9568
9579
  }),
9569
- stopEnabled: (lane) => {
9570
- const resolution = resolveLaneCompany(ctx.hqRoot(), lane);
9571
- const company = resolution.company ?? undefined;
9572
- return readLanesRegistryFlag(LANE_REAP_STOP_FLAG, {
9573
- company,
9574
- ...(company ? { companyUidSource: laneCompanyUidSource(resolution.source) } : {}),
9575
- env: ctx.env,
9576
- });
9577
- },
9580
+ stopEnabled: (lane) => readLaneReapStopEnabled(ctx.hqRoot(), lane, ctx.env),
9578
9581
  }, wrap);
9579
9582
  registerLaneDropboxRepairCommand(lanes, {
9580
9583
  hqRoot: ctx.hqRoot,
@@ -595,6 +595,7 @@ export async function runDrainHook(env, input = {}, deps = {}) {
595
595
  : await readLanesRegistryFlagFailOpen(LANE_DROPBOX_LIFECYCLE_DELIVERY_FLAG, {
596
596
  ...(company ? { company } : {}),
597
597
  env,
598
+ defaultValue: true,
598
599
  });
599
600
  }
600
601
  catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.345.74",
3
+ "version": "5.345.75",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {