@aexol/spectral 0.9.156 → 0.9.157

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/dist/cli.js CHANGED
@@ -13,20 +13,12 @@
13
13
  * - `spectral --version` / `--help` → branded short-circuits, no auth needed.
14
14
  * - anything else → error with usage hint.
15
15
  */
16
- import { readFileSync } from "node:fs";
17
- import { dirname, resolve } from "node:path";
18
- import { fileURLToPath } from "node:url";
19
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ import { getVersion } from "./version.js";
20
17
  // ---- Read our own version ----------------------------------------------------
21
- let VERSION = process.env.npm_package_version ?? "0.0.0";
22
- try {
23
- const pkgPath = resolve(__dirname, "..", "package.json");
24
- const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
25
- VERSION = pkg.version;
26
- }
27
- catch {
28
- // Standalone Bun binaries do not carry the source package.json.
29
- }
18
+ // Centralized in src/version.ts so the standalone Bun binary, the npm
19
+ // install, and the electron app all resolve the same real version instead of
20
+ // silently falling back to "0.0.0".
21
+ const VERSION = getVersion();
30
22
  const TAGLINE = "Coding agent that never sleeps";
31
23
  // ---- Branded helpers ---------------------------------------------------------
32
24
  function printVersion() {
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AA0BH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAWlE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAsBrE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA6B9D;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAmelF;AA+DD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAa5E"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAwBH,OAAO,EAAE,WAAW,EAAmB,MAAM,oBAAoB,CAAC;AAWlE,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAmB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAWrE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CA6B9D;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,KAAK,EAAE,YAAY,CAAC;IACpB,wDAAwD;IACxD,OAAO,EAAE,oBAAoB,CAAC;IAC9B,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAmelF;AA+DD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAa5E"}
@@ -27,10 +27,8 @@
27
27
  * `relayUrlOverride` + `fetchImpl` + `webSocketImpl` to point at an
28
28
  * in-process fake backend.
29
29
  */
30
- import { readFileSync } from "node:fs";
31
30
  import { hostname } from "node:os";
32
- import { dirname, join, resolve } from "node:path";
33
- import { fileURLToPath } from "node:url";
31
+ import { join } from "node:path";
34
32
  import { getConfigDir } from "../config.js";
35
33
  import { readStudioBinding } from "../studio-binding.js";
36
34
  import { NATIVE_EXTENSIONS, buildNativeExtensionsInfo } from "../sdk/coding-agent/core/extensions/native-extensions.js";
@@ -46,24 +44,14 @@ import { SessionStreamManager } from "../server/session-stream.js";
46
44
  import { gracefulShutdown } from "../server/shutdown.js";
47
45
  import { getLiveMcpState } from "../mcp/state-getter.js";
48
46
  import { preflightSqlite, SessionStore } from "../server/storage.js";
49
- const __dirname = dirname(fileURLToPath(import.meta.url));
50
47
  /** Default backend base URL when neither env nor override is set. */
51
48
  const DEFAULT_BACKEND_URL = "https://api.aexol.ai";
52
- function readPackageVersion() {
53
- // dist/commands/serve.js → ../../package.json
54
- // src/commands/serve.ts../../package.json (tsx / vitest)
55
- // In a Bun standalone binary the source tree is not present, so the
56
- // package.json lookup below fails. Return a fallback version instead of
57
- // crashing the serve process.
58
- try {
59
- const pkgPath = resolve(__dirname, "..", "..", "package.json");
60
- const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
61
- return pkg.version;
62
- }
63
- catch {
64
- return process.env.npm_package_version ?? "0.0.0";
65
- }
66
- }
49
+ import { getVersion } from "../version.js";
50
+ // CLI version is resolved centrally via getVersion() (see src/version.ts):
51
+ // env override → package.json read "0.0.0". For standalone Bun binaries the
52
+ // version is also inlined at compile time via `bun build --define` in
53
+ // build-standalone.sh, so the relay always receives the real version instead
54
+ // of falling back to "0.0.0".
67
55
  /**
68
56
  * Translate a backend HTTP(S) base URL to the relay WS(S) URL.
69
57
  * `http://x:y` → `ws://x:y/agent-connection`
@@ -130,7 +118,7 @@ export function parseServeArgs(args) {
130
118
  export async function runServe(opts = {}) {
131
119
  const cfg = await requireLogin();
132
120
  const cwd = opts.cwd ?? process.cwd();
133
- const version = readPackageVersion();
121
+ const version = getVersion();
134
122
  const installSignalHandlers = opts.installSignalHandlers ?? true;
135
123
  const silent = opts.silent ?? false;
136
124
  const dbPath = opts.dbPath ?? join(getConfigDir(), "sessions.db");
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsOH;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8H7D"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2NH;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8H7D"}
@@ -10,28 +10,19 @@
10
10
  */
11
11
  import { createHash } from "node:crypto";
12
12
  import { chmod, mkdtemp, rename, rm, stat, writeFile, } from "node:fs/promises";
13
- import { readFileSync } from "node:fs";
14
13
  import { tmpdir } from "node:os";
15
- import { basename, dirname, join, resolve } from "node:path";
16
- import { fileURLToPath } from "node:url";
14
+ import { basename, dirname, join } from "node:path";
17
15
  import pc from "picocolors";
18
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ import { getVersion } from "../version.js";
19
17
  /** Base URL for the Aexol release manifest / binary downloads. */
20
18
  const RELEASE_BASE = "https://api.aexol.ai/api/releases/download";
21
19
  /**
22
- * Resolve the current CLI version. Reads package.json adjacent to this module
23
- * when available (dev / npm install), falling back to the npm-injected env var
24
- * and finally "0.0.0"mirroring the logic in cli.ts.
20
+ * Resolve the current CLI version via the centralized getVersion() helper
21
+ * (src/version.ts), which works for npm install, standalone Bun binaries, and
22
+ * the Electron appall of which previously fell back to "0.0.0".
25
23
  */
26
24
  function currentVersion() {
27
- try {
28
- const pkgPath = resolve(__dirname, "..", "package.json");
29
- const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
30
- return pkg.version;
31
- }
32
- catch {
33
- return process.env.npm_package_version ?? "0.0.0";
34
- }
25
+ return getVersion();
35
26
  }
36
27
  /**
37
28
  * Compare two semver-ish version strings (e.g. "1.2.3", "v1.2.3").
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/sdk/coding-agent/config.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAEhE,UAAU,qBAAqB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAkB,SAAQ,qBAAqB;IAC/D,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAChC;AAsBD,wBAAgB,mBAAmB,IAAI,aAAa,CAcnD;AAyKD,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,iBAAiB,GAAG,SAAS,CAO/B;AAED,wBAAgB,mCAAmC,CAClD,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,MAAM,CAUR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOhE;AAMD;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAiBtC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED;;;;+BAI+B;AAC/B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,iCAAiC;AACjC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AA4BD,eAAO,MAAM,YAAY,EAAE,MAA+B,CAAC;AAC3D,eAAO,MAAM,QAAQ,EAAE,MAAyC,CAAC;AACjE,eAAO,MAAM,SAAS,EAAE,MAAmD,CAAC;AAC5E,eAAO,MAAM,eAAe,EAAE,MAAqD,CAAC;AACpF,eAAO,MAAM,OAAO,EAAE,MAA+B,CAAC;AAGtD,eAAO,MAAM,aAAa,QAA+C,CAAC;AAC1E,eAAO,MAAM,eAAe,QAAuD,CAAC;AAEpF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAMD,gEAAgE;AAChE,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,gCAAgC;AAChC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,kCAAkC;AAClC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/sdk/coding-agent/config.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAEhE,UAAU,qBAAqB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAkB,SAAQ,qBAAqB;IAC/D,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAChC;AAsBD,wBAAgB,mBAAmB,IAAI,aAAa,CAcnD;AAyKD,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,iBAAiB,GAAG,SAAS,CAO/B;AAED,wBAAgB,mCAAmC,CAClD,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,MAAM,CAUR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOhE;AAMD;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAiBtC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED;;;;+BAI+B;AAC/B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,iCAAiC;AACjC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AA4BD,eAAO,MAAM,YAAY,EAAE,MAA+B,CAAC;AAC3D,eAAO,MAAM,QAAQ,EAAE,MAAyC,CAAC;AACjE,eAAO,MAAM,SAAS,EAAE,MAAmD,CAAC;AAC5E,eAAO,MAAM,eAAe,EAAE,MAAqD,CAAC;AACpF,eAAO,MAAM,OAAO,EAAE,MAAqB,CAAC;AAG5C,eAAO,MAAM,aAAa,QAA+C,CAAC;AAC1E,eAAO,MAAM,eAAe,QAAuD,CAAC;AAEpF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAMD,gEAAgE;AAChE,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,gCAAgC;AAChC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,kCAAkC;AAClC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
@@ -4,6 +4,7 @@ import { basename, dirname, join, resolve, sep, win32 } from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  import { spawnProcessSync } from "./utils/child-process.js";
6
6
  import { normalizePath } from "./utils/paths.js";
7
+ import { getVersion } from "../../version.js";
7
8
  // =============================================================================
8
9
  // Package Detection
9
10
  // =============================================================================
@@ -283,7 +284,7 @@ export const PACKAGE_NAME = pkg.name || "index.ts";
283
284
  export const APP_NAME = spectralConfigName || "spectral";
284
285
  export const APP_TITLE = spectralConfigName ? APP_NAME : "spectral";
285
286
  export const CONFIG_DIR_NAME = pkg.spectralConfig?.configDir || ".spectral";
286
- export const VERSION = pkg.version || "0.0.0";
287
+ export const VERSION = getVersion();
287
288
  // e.g., SPECTRAL_CODING_AGENT_DIR
288
289
  export const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;
289
290
  export const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;
@@ -0,0 +1,4 @@
1
+ /** Test-only hook to reset the version cache. Not part of the public API. */
2
+ export declare function _resetVersionCacheForTests(): void;
3
+ export declare function getVersion(): string;
4
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAmEA,6EAA6E;AAC7E,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED,wBAAgB,UAAU,IAAI,MAAM,CAuBnC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Central CLI version resolution.
3
+ *
4
+ * Why this exists:
5
+ * The standalone spectral binary is produced with `bun build --compile`.
6
+ * Inside a compiled Bun binary there is no real `package.json` next to the
7
+ * emitted code, so a `readFileSync(resolve(__dirname, ...))` lookup throws
8
+ * and the code falls back to `process.env.npm_package_version`. That env var
9
+ * is only set when running via `npm run`/`npx` — a compiled binary is never
10
+ * launched that way — so the version silently becomes `"0.0.0"`.
11
+ *
12
+ * That `"0.0.0"` is then reported to the relay as the machine's
13
+ * `runtimeInfo.version` and surfaces in the Studio landing as the bogus
14
+ * "Your CLI (v0.0.0) is outdated" toast.
15
+ *
16
+ * Resolution order:
17
+ * 1. `SPECTRAL_CLI_VERSION` — explicit override (also used by tests).
18
+ * 2. `process.env.npm_package_version` — set by npm/npx, AND inlined at
19
+ * compile time by `bun build --define` in build-standalone.sh, so the
20
+ * standalone binary bakes in the real version.
21
+ * 3. `package.json` read from disk — works for `npm install` / `npm run dev`
22
+ * where the file ships alongside `dist/`.
23
+ * 4. `"0.0.0"` — last-resort fallback.
24
+ */
25
+ import { readFileSync } from "node:fs";
26
+ import { dirname, resolve } from "node:path";
27
+ import { fileURLToPath } from "node:url";
28
+ const __dirname = dirname(fileURLToPath(import.meta.url));
29
+ /**
30
+ * Walk up from `__dirname` looking for the nearest `package.json` that looks
31
+ * like the @aexol/spectral package (has a version field). This mirrors the
32
+ * `getPackageDir()` walker in config.ts and survives both `dist/` and `src/`
33
+ * layouts used by npm-installed packages.
34
+ */
35
+ function findPackageVersion() {
36
+ try {
37
+ let dir = __dirname;
38
+ while (true) {
39
+ const candidate = resolve(dir, "package.json");
40
+ try {
41
+ const pkg = JSON.parse(readFileSync(candidate, "utf8"));
42
+ // Accept the spectral package by name, or any package.json that has a
43
+ // version field (the walker stops at the first match, which for a
44
+ // standard `npm install @aexol/spectral` layout is the right one).
45
+ if (pkg.name === "@aexol/spectral" && pkg.version) {
46
+ return pkg.version;
47
+ }
48
+ }
49
+ catch {
50
+ // not a parseable package.json or missing — keep walking
51
+ }
52
+ const parent = dirname(dir);
53
+ if (parent === dir)
54
+ break; // reached filesystem root
55
+ dir = parent;
56
+ }
57
+ }
58
+ catch {
59
+ // ignore filesystem errors entirely
60
+ }
61
+ return null;
62
+ }
63
+ let _cached;
64
+ /** Test-only hook to reset the version cache. Not part of the public API. */
65
+ export function _resetVersionCacheForTests() {
66
+ _cached = undefined;
67
+ }
68
+ export function getVersion() {
69
+ if (_cached !== undefined)
70
+ return _cached;
71
+ const override = process.env.SPECTRAL_CLI_VERSION;
72
+ if (override && override.length > 0) {
73
+ _cached = override;
74
+ return _cached;
75
+ }
76
+ const envVersion = process.env.npm_package_version;
77
+ if (envVersion && envVersion.length > 0 && envVersion !== "0.0.0") {
78
+ _cached = envVersion;
79
+ return _cached;
80
+ }
81
+ const fileVersion = findPackageVersion();
82
+ if (fileVersion) {
83
+ _cached = fileVersion;
84
+ return _cached;
85
+ }
86
+ _cached = "0.0.0";
87
+ return _cached;
88
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aexol/spectral",
3
- "version": "0.9.156",
3
+ "version": "0.9.157",
4
4
  "description": "AI coding agent for Aexol with relay-based browser access.",
5
5
  "type": "module",
6
6
  "private": false,