@indigoai-us/hq-cli 5.94.0 → 5.94.1

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,30 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.94.1]
6
+
7
+ ### Fixed
8
+
9
+ - The CLI now actually uses its bundled qmd. Package-local resolution had never
10
+ worked, so every install silently fell through to whatever qmd was on `PATH`,
11
+ and a host without a global qmd reported `skipped` — defeating the reason
12
+ `@tobilu/qmd` is a dependency and undoing in practice what 5.93.x set out to
13
+ fix for Node 26 global installs. Two independent causes, both silent: the
14
+ resolver looked for `<pkg>/qmd` while the package declares `bin/qmd`, and the
15
+ package-manifest lookup throws `ERR_PACKAGE_PATH_NOT_EXPORTED` on qmd 2.x,
16
+ which also blanked the version in `hq index status`. Both now follow the
17
+ package-manager contract: the binary via `node_modules/.bin/qmd`, the version
18
+ read from `node_modules/@tobilu/qmd/package.json`. (#333)
19
+
20
+ ### Added
21
+
22
+ - A shell-vs-native differential for `hq index background`, run against a frozen
23
+ copy of the pre-migration `qmd-reindex-bg.sh`: agent-box short-circuit before
24
+ any qmd lookup or lock, empty-`HOME` silence, `cleanup → update → embed`
25
+ ordering with completion stamp, no stamp after a failed update, and no
26
+ competing writer behind a held lock. It is what surfaced the resolution bug
27
+ above. (#333)
28
+
5
29
  ## [5.94.0]
6
30
 
7
31
  ### Removed
@@ -28,7 +28,13 @@ export type ResolveQmdBinOptions = {
28
28
  packageBin?: () => string | undefined;
29
29
  pathBin?: () => string | undefined;
30
30
  };
31
- /** Return the pinned package version when qmd is supplied by this CLI. */
31
+ /**
32
+ * Return the pinned package version when qmd is supplied by this CLI.
33
+ *
34
+ * Read from disk rather than `require('@tobilu/qmd/package.json')`: qmd 2.x does
35
+ * not export package.json, so the require form throws and the version silently
36
+ * disappeared from `hq index status`. Same root cause as packageLocalBin.
37
+ */
32
38
  export declare function resolveQmdVersion(): string | undefined;
33
39
  /** Resolve qmd without relying on a globally installed copy. */
34
40
  export declare function resolveQmdBin(options?: ResolveQmdBinOptions): string;
@@ -2,6 +2,7 @@ import { spawnSync } from 'node:child_process';
2
2
  import * as fs from 'node:fs';
3
3
  import { createRequire } from 'node:module';
4
4
  import * as path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
5
6
  const require = createRequire(import.meta.url);
6
7
  export class QmdBinaryMissingError extends Error {
7
8
  name = 'QmdBinaryMissingError';
@@ -32,24 +33,68 @@ function isExecutable(candidate) {
32
33
  return false;
33
34
  }
34
35
  }
36
+ /**
37
+ * Locate the bundled qmd through the dependency-bin link the package manager
38
+ * installs, walking up from this module.
39
+ *
40
+ * Two earlier approaches were wrong and both failed silently, so every host fell
41
+ * through to PATH and a machine without a global qmd reported "skipped" — which
42
+ * defeats the point of depending on qmd at all:
43
+ *
44
+ * - `<pkg>/qmd` guessed a filename; the package declares `bin/qmd`.
45
+ * - `require.resolve('@tobilu/qmd/package.json')` throws
46
+ * ERR_PACKAGE_PATH_NOT_EXPORTED on qmd 2.x, whose `exports` map does not
47
+ * expose package.json.
48
+ *
49
+ * `node_modules/.bin/qmd` is the contract every package manager honours and is
50
+ * independent of the dependency's own exports map.
51
+ */
35
52
  function packageLocalBin() {
36
- try {
37
- const packageJson = require.resolve('@tobilu/qmd/package.json');
38
- return path.join(path.dirname(packageJson), 'qmd');
39
- }
40
- catch {
41
- return undefined;
53
+ const names = process.platform === 'win32' ? ['qmd.cmd', 'qmd.exe', 'qmd'] : ['qmd'];
54
+ let directory = path.dirname(fileURLToPath(import.meta.url));
55
+ for (let depth = 0; depth < 10; depth++) {
56
+ for (const name of names) {
57
+ const candidate = path.join(directory, 'node_modules', '.bin', name);
58
+ if (fs.existsSync(candidate))
59
+ return candidate;
60
+ }
61
+ const parent = path.dirname(directory);
62
+ if (parent === directory)
63
+ break;
64
+ directory = parent;
42
65
  }
66
+ return undefined;
43
67
  }
44
- /** Return the pinned package version when qmd is supplied by this CLI. */
68
+ /**
69
+ * Return the pinned package version when qmd is supplied by this CLI.
70
+ *
71
+ * Read from disk rather than `require('@tobilu/qmd/package.json')`: qmd 2.x does
72
+ * not export package.json, so the require form throws and the version silently
73
+ * disappeared from `hq index status`. Same root cause as packageLocalBin.
74
+ */
45
75
  export function resolveQmdVersion() {
46
- try {
47
- const packageJson = require('@tobilu/qmd/package.json');
48
- return typeof packageJson.version === 'string' ? packageJson.version : undefined;
49
- }
50
- catch {
51
- return undefined;
76
+ // Walk for the package directory itself. Neither require() nor the .bin entry
77
+ // works: qmd 2.x does not export package.json, and .bin/qmd is a generated
78
+ // shim (not a symlink) under pnpm's hoisted linker, so resolving it lands back
79
+ // in this package rather than qmd's.
80
+ let directory = path.dirname(fileURLToPath(import.meta.url));
81
+ for (let depth = 0; depth < 10; depth++) {
82
+ const manifest = path.join(directory, 'node_modules', '@tobilu', 'qmd', 'package.json');
83
+ if (fs.existsSync(manifest)) {
84
+ try {
85
+ const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8'));
86
+ if (typeof parsed.version === 'string')
87
+ return parsed.version;
88
+ }
89
+ catch { /* unreadable manifest: report no version rather than throwing */ }
90
+ return undefined;
91
+ }
92
+ const parent = path.dirname(directory);
93
+ if (parent === directory)
94
+ break;
95
+ directory = parent;
52
96
  }
97
+ return undefined;
53
98
  }
54
99
  function pathBin() {
55
100
  const paths = (process.env.PATH ?? '').split(path.delimiter).filter(Boolean);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.94.0",
3
+ "version": "5.94.1",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {