@cleocode/paths 2026.5.128 → 2026.5.130
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/cleo-paths.d.ts +23 -0
- package/dist/cleo-paths.d.ts.map +1 -1
- package/dist/cleo-paths.js +55 -13
- package/dist/cleo-paths.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/node-version-gate.d.ts +126 -0
- package/dist/node-version-gate.d.ts.map +1 -0
- package/dist/node-version-gate.js +224 -0
- package/dist/node-version-gate.js.map +1 -0
- package/package.json +2 -2
package/dist/cleo-paths.d.ts
CHANGED
|
@@ -125,6 +125,29 @@ export interface ResolvedProject {
|
|
|
125
125
|
/** The legacy UUID from project-info.json, if present. */
|
|
126
126
|
legacyUUID?: string;
|
|
127
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Canonicalize a filesystem path across operating systems — resolve symlinks
|
|
130
|
+
* and mount/alias divergence (macOS `/var` → `/private/var`, Windows
|
|
131
|
+
* drive-letter case + 8.3 short names, Linux bind-mounts) via
|
|
132
|
+
* {@link realpathSync}.
|
|
133
|
+
*
|
|
134
|
+
* Falls back to the lexically-resolved absolute path when the target does not
|
|
135
|
+
* exist on disk, so identity/root computations never throw for a moved,
|
|
136
|
+
* deleted, or not-yet-created project path.
|
|
137
|
+
*
|
|
138
|
+
* **SSoT:** this is the single path-canonicalization entry point for the CLEO
|
|
139
|
+
* SDK. Never call `realpathSync` ad-hoc for path identity — route through here
|
|
140
|
+
* so the OS-specific normalization stays consistent across every consumer and
|
|
141
|
+
* test (notably the macOS `/var` vs `/private/var` split).
|
|
142
|
+
*
|
|
143
|
+
* @param p - A relative or absolute filesystem path.
|
|
144
|
+
* @returns The realpath-canonicalized absolute path, or the lexically-resolved
|
|
145
|
+
* absolute path when the target does not exist.
|
|
146
|
+
*
|
|
147
|
+
* @public
|
|
148
|
+
* @task T11023
|
|
149
|
+
*/
|
|
150
|
+
export declare function canonicalizePath(p: string): string;
|
|
128
151
|
/**
|
|
129
152
|
* Compute the canonical project ID for a given repository path (T9149/T11023).
|
|
130
153
|
*
|
package/dist/cleo-paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleo-paths.d.ts","sourceRoot":"","sources":["../src/cleo-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"cleo-paths.d.ts","sourceRoot":"","sources":["../src/cleo-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAeH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAwB7B;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,aAAa,CAEpD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,CAE9C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAelD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAMvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuDD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CASlD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWlE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA0CxE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkExE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
|
package/dist/cleo-paths.js
CHANGED
|
@@ -11,11 +11,24 @@
|
|
|
11
11
|
import { execFileSync } from 'node:child_process';
|
|
12
12
|
import { createHash } from 'node:crypto';
|
|
13
13
|
import { existsSync, readFileSync, realpathSync } from 'node:fs';
|
|
14
|
+
import { createRequire } from 'node:module';
|
|
14
15
|
import { homedir } from 'node:os';
|
|
15
16
|
import { dirname, join, resolve } from 'node:path';
|
|
16
|
-
import { DatabaseSync } from 'node:sqlite';
|
|
17
17
|
import { createPlatformPathsResolver, } from './platform-paths.js';
|
|
18
18
|
const TEMPLATES_SUBDIR = 'templates';
|
|
19
|
+
/**
|
|
20
|
+
* Returns the `node:sqlite` `DatabaseSync` constructor, loaded on first use.
|
|
21
|
+
*
|
|
22
|
+
* Loaded via `createRequire` so that importing this module does not eagerly pull
|
|
23
|
+
* in `node:sqlite` — preserving the lazy-init invariant (T1331/T11280).
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
function getDatabaseSyncCtor() {
|
|
28
|
+
const _require = createRequire(import.meta.url);
|
|
29
|
+
const mod = _require('node:sqlite');
|
|
30
|
+
return mod.DatabaseSync;
|
|
31
|
+
}
|
|
19
32
|
const cleoResolver = createPlatformPathsResolver('cleo', 'CLEO_HOME', 'CLEO_CONFIG_HOME');
|
|
20
33
|
/**
|
|
21
34
|
* Get OS-appropriate paths for CLEO's global directories.
|
|
@@ -201,6 +214,39 @@ function _readProjectInfoName(repoRoot) {
|
|
|
201
214
|
return undefined;
|
|
202
215
|
}
|
|
203
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Canonicalize a filesystem path across operating systems — resolve symlinks
|
|
219
|
+
* and mount/alias divergence (macOS `/var` → `/private/var`, Windows
|
|
220
|
+
* drive-letter case + 8.3 short names, Linux bind-mounts) via
|
|
221
|
+
* {@link realpathSync}.
|
|
222
|
+
*
|
|
223
|
+
* Falls back to the lexically-resolved absolute path when the target does not
|
|
224
|
+
* exist on disk, so identity/root computations never throw for a moved,
|
|
225
|
+
* deleted, or not-yet-created project path.
|
|
226
|
+
*
|
|
227
|
+
* **SSoT:** this is the single path-canonicalization entry point for the CLEO
|
|
228
|
+
* SDK. Never call `realpathSync` ad-hoc for path identity — route through here
|
|
229
|
+
* so the OS-specific normalization stays consistent across every consumer and
|
|
230
|
+
* test (notably the macOS `/var` vs `/private/var` split).
|
|
231
|
+
*
|
|
232
|
+
* @param p - A relative or absolute filesystem path.
|
|
233
|
+
* @returns The realpath-canonicalized absolute path, or the lexically-resolved
|
|
234
|
+
* absolute path when the target does not exist.
|
|
235
|
+
*
|
|
236
|
+
* @public
|
|
237
|
+
* @task T11023
|
|
238
|
+
*/
|
|
239
|
+
export function canonicalizePath(p) {
|
|
240
|
+
const resolved = resolve(p);
|
|
241
|
+
try {
|
|
242
|
+
return realpathSync(resolved);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// Target does not exist (moved / deleted / not-yet-created) — the
|
|
246
|
+
// lexically-resolved absolute path is the best canonical form available.
|
|
247
|
+
return resolved;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
204
250
|
/**
|
|
205
251
|
* Compute the canonical project ID for a given repository path (T9149/T11023).
|
|
206
252
|
*
|
|
@@ -221,7 +267,7 @@ function _readProjectInfoName(repoRoot) {
|
|
|
221
267
|
* @task T9149
|
|
222
268
|
*/
|
|
223
269
|
export function computeCanonicalProjectId(repoPath) {
|
|
224
|
-
const realRepoPath =
|
|
270
|
+
const realRepoPath = canonicalizePath(repoPath);
|
|
225
271
|
const gitRoot = _findGitRootSync(realRepoPath);
|
|
226
272
|
const effectiveRoot = gitRoot ?? realRepoPath;
|
|
227
273
|
const remoteUrl = gitRoot ? _findGitRemoteUrlSync(gitRoot) : null;
|
|
@@ -281,17 +327,12 @@ export function resolveProjectByCwd(cwd) {
|
|
|
281
327
|
const raw = readFileSync(infoPath, 'utf-8');
|
|
282
328
|
const data = JSON.parse(raw);
|
|
283
329
|
if (typeof data.projectId === 'string' && data.projectId.length > 0) {
|
|
284
|
-
// T11023: Normalize projectRoot via
|
|
285
|
-
// divergence — same repo at
|
|
286
|
-
//
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
catch {
|
|
292
|
-
// realpathSync fails on nonexistent paths — fall back to resolved path
|
|
293
|
-
realRoot = current;
|
|
294
|
-
}
|
|
330
|
+
// T11023: Normalize projectRoot via the canonicalizePath SSoT to
|
|
331
|
+
// handle cross-mount + cross-OS divergence — same repo at
|
|
332
|
+
// /mnt/projects/X and /workspace/X (and macOS /var vs /private/var)
|
|
333
|
+
// resolves to the same real path (AC2, AC3). Falls back to the
|
|
334
|
+
// lexical path when `current` no longer exists on disk.
|
|
335
|
+
const realRoot = canonicalizePath(current);
|
|
295
336
|
// T11023: Compute canonical projectId using T9149 algorithm
|
|
296
337
|
// (git-root + realpath fingerprint) for mount-invariant identity (AC1).
|
|
297
338
|
const canonicalId = computeCanonicalProjectId(realRoot);
|
|
@@ -343,6 +384,7 @@ export function resolveCanonicalCleoDir(projectId) {
|
|
|
343
384
|
return null;
|
|
344
385
|
let db;
|
|
345
386
|
try {
|
|
387
|
+
const DatabaseSync = getDatabaseSyncCtor();
|
|
346
388
|
db = new DatabaseSync(nexusDbPath, { readOnly: true }); // db-open-allowed: leaf path package cannot depend on core DB chokepoint
|
|
347
389
|
// Try direct project_registry lookup first.
|
|
348
390
|
const directStmt = db.prepare('SELECT project_path FROM project_registry WHERE project_id = ? LIMIT 1');
|
package/dist/cleo-paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleo-paths.js","sourceRoot":"","sources":["../src/cleo-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cleo-paths.js","sourceRoot":"","sources":["../src/cleo-paths.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* @task T11008
|
|
22
22
|
*/
|
|
23
23
|
export { isAbsolutePath } from './abs-path.js';
|
|
24
|
-
export { _resetCleoPlatformPathsCache, computeCanonicalProjectId, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, legacyProjectId, type ResolvedProject, resolveCanonicalCleoDir, resolveLegacyCleoDir, resolveProjectByCwd, } from './cleo-paths.js';
|
|
24
|
+
export { _resetCleoPlatformPathsCache, canonicalizePath, computeCanonicalProjectId, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, legacyProjectId, type ResolvedProject, resolveCanonicalCleoDir, resolveLegacyCleoDir, resolveProjectByCwd, } from './cleo-paths.js';
|
|
25
|
+
export { type EnforceOptions, enforceNodeVersion, evaluateNodeVersion, FALLBACK_MIN_NODE, getRequiredNodeVersion, type NodeManager, type NodeVersionVerdict, parseSemver, type Semver, type UpgradeHint, } from './node-version-gate.js';
|
|
25
26
|
export { createPlatformPathsResolver, type PlatformPaths, type PlatformPathsResolver, type SystemInfo, } from './platform-paths.js';
|
|
26
27
|
export { computeProjectHash, getCleoWorktreesRoot, resolveTaskWorktreePath, resolveWorktreeIndexPath, resolveWorktreeRootForHash, } from './worktree-paths.js';
|
|
27
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,8BAA8B,EAC9B,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EACf,KAAK,eAAe,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,EAC3B,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,4BAA4B,EAC5B,gBAAgB,EAChB,yBAAyB,EACzB,8BAA8B,EAC9B,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EACf,KAAK,eAAe,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,cAAc,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,WAAW,EACX,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,2BAA2B,EAC3B,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,UAAU,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* @task T11008
|
|
22
22
|
*/
|
|
23
23
|
export { isAbsolutePath } from './abs-path.js';
|
|
24
|
-
export { _resetCleoPlatformPathsCache, computeCanonicalProjectId, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, legacyProjectId, resolveCanonicalCleoDir, resolveLegacyCleoDir, resolveProjectByCwd, } from './cleo-paths.js';
|
|
24
|
+
export { _resetCleoPlatformPathsCache, canonicalizePath, computeCanonicalProjectId, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, legacyProjectId, resolveCanonicalCleoDir, resolveLegacyCleoDir, resolveProjectByCwd, } from './cleo-paths.js';
|
|
25
|
+
export { enforceNodeVersion, evaluateNodeVersion, FALLBACK_MIN_NODE, getRequiredNodeVersion, parseSemver, } from './node-version-gate.js';
|
|
25
26
|
export { createPlatformPathsResolver, } from './platform-paths.js';
|
|
26
27
|
export { computeProjectHash, getCleoWorktreesRoot, resolveTaskWorktreePath, resolveWorktreeIndexPath, resolveWorktreeRootForHash, } from './worktree-paths.js';
|
|
27
28
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,8BAA8B,EAC9B,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EAEf,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,GAI5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,4BAA4B,EAC5B,gBAAgB,EAChB,yBAAyB,EACzB,8BAA8B,EAC9B,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EAEf,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EAGtB,WAAW,GAGZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,2BAA2B,GAI5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node runtime-version enforcement gate (SSoT).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for "is the running Node new enough to run CLEO".
|
|
5
|
+
* The minimum is read from this package's own shipped `engines.node` at
|
|
6
|
+
* runtime — NOT a hardcoded constant — so bumping the floor is a one-line
|
|
7
|
+
* `package.json` edit and the gate evolves with it. A CI lint
|
|
8
|
+
* (`scripts/lint-node-engine-ssot.mjs`) keeps every workspace package's
|
|
9
|
+
* `engines.node` equal to root's, so the value the gate reads is authoritative.
|
|
10
|
+
*
|
|
11
|
+
* Lives in `@cleocode/paths` — the zero-dep leaf (only `env-paths`) that is
|
|
12
|
+
* importable BEFORE any `@cleocode/core` import. The CLI guard must run here,
|
|
13
|
+
* not at `node:sqlite` load, so an under-floor Node fails with an actionable
|
|
14
|
+
* message instead of a cryptic `ERR_UNKNOWN_BUILTIN_MODULE` / divergent-SQLite
|
|
15
|
+
* behavior. (Importing this package does NOT eagerly load `node:sqlite` — that
|
|
16
|
+
* is lazy via `createRequire`; see `cleo-paths.ts`.)
|
|
17
|
+
*
|
|
18
|
+
* Why a full-semver floor and not a major-only check: 24.13.1 satisfies
|
|
19
|
+
* `major >= 24` yet is below 24.16.0, where the bundled SQLite WAL-reset
|
|
20
|
+
* corruption fix (SQLite 3.53.0) landed. The major-only guards
|
|
21
|
+
* (`cli/index.ts`, `dependencies.ts:checkNode`) waved it through, then the
|
|
22
|
+
* persistence layer diverged from CI. This gate compares full semver.
|
|
23
|
+
*
|
|
24
|
+
* @packageDocumentation
|
|
25
|
+
* @task T11281
|
|
26
|
+
* @task T11242
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Last-resort floor used only when this package's `engines.node` cannot be
|
|
30
|
+
* read (e.g. a corrupted install). Kept equal to root `engines.node` by the
|
|
31
|
+
* `lint-node-engine-ssot` CI gate so it can never silently lie.
|
|
32
|
+
*/
|
|
33
|
+
export declare const FALLBACK_MIN_NODE = "24.16.0";
|
|
34
|
+
/** A parsed `major.minor.patch` triple. */
|
|
35
|
+
export interface Semver {
|
|
36
|
+
major: number;
|
|
37
|
+
minor: number;
|
|
38
|
+
patch: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse the first `x.y.z` triple out of a version fragment such as
|
|
42
|
+
* `24.16.0`, `v24.16.0`, or a range like `>=24.16.0 <27`.
|
|
43
|
+
*
|
|
44
|
+
* @param raw - The version or range string.
|
|
45
|
+
* @returns The parsed {@link Semver}, or `null` when no triple is present.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseSemver(raw: string): Semver | null;
|
|
48
|
+
/**
|
|
49
|
+
* Read the minimum Node version from this package's shipped `engines.node`
|
|
50
|
+
* (the SSoT). Falls back to {@link FALLBACK_MIN_NODE} when the manifest is
|
|
51
|
+
* unreadable or declares no parseable version.
|
|
52
|
+
*
|
|
53
|
+
* @returns A normalized `major.minor.patch` string.
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
export declare function getRequiredNodeVersion(): string;
|
|
58
|
+
/** A version manager (or platform installer) CLEO can suggest for upgrading. */
|
|
59
|
+
export type NodeManager = 'fnm' | 'nvm' | 'n' | 'volta' | 'asdf' | 'brew' | 'winget' | 'choco' | 'nodesource';
|
|
60
|
+
/** A concrete, copy-pasteable upgrade instruction. */
|
|
61
|
+
export interface UpgradeHint {
|
|
62
|
+
manager: NodeManager;
|
|
63
|
+
command: string;
|
|
64
|
+
note?: string;
|
|
65
|
+
}
|
|
66
|
+
/** Result of evaluating the running Node against the required floor. */
|
|
67
|
+
export interface NodeVersionVerdict {
|
|
68
|
+
compliant: boolean;
|
|
69
|
+
current: string;
|
|
70
|
+
required: string;
|
|
71
|
+
platform: NodeJS.Platform;
|
|
72
|
+
arch: string;
|
|
73
|
+
/** Ordered best-first; empty when compliant. */
|
|
74
|
+
hints: UpgradeHint[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Evaluate the running Node against the required floor. Pure and
|
|
78
|
+
* side-effect-free (no `process.exit`, no I/O beyond the SSoT manifest read) —
|
|
79
|
+
* safe to call from `doctor`/`health` and unit tests.
|
|
80
|
+
*
|
|
81
|
+
* @param currentRaw - The Node version to evaluate. Defaults to
|
|
82
|
+
* `process.versions.node`.
|
|
83
|
+
* @returns The {@link NodeVersionVerdict}.
|
|
84
|
+
*
|
|
85
|
+
* @public
|
|
86
|
+
*/
|
|
87
|
+
export declare function evaluateNodeVersion(currentRaw?: string): NodeVersionVerdict;
|
|
88
|
+
/** Options controlling {@link enforceNodeVersion}. */
|
|
89
|
+
export interface EnforceOptions {
|
|
90
|
+
/**
|
|
91
|
+
* `enforce` (default): print guidance + exit 1.
|
|
92
|
+
* `warn`: print guidance + continue.
|
|
93
|
+
* `auto`: best-effort install, then exit 1 ("open a new shell + re-run").
|
|
94
|
+
* Default resolves to `auto` when `CLEO_NODE_AUTO_UPGRADE=1`, else `enforce`.
|
|
95
|
+
*/
|
|
96
|
+
mode?: 'enforce' | 'warn' | 'auto';
|
|
97
|
+
/** stderr writer (injectable for tests). */
|
|
98
|
+
write?: (s: string) => void;
|
|
99
|
+
/** process exit (injectable for tests). */
|
|
100
|
+
exit?: (code: number) => never;
|
|
101
|
+
/**
|
|
102
|
+
* Node version to evaluate. Defaults to `process.versions.node`. Injectable
|
|
103
|
+
* so tests assert a fixed verdict deterministically on any runtime (otherwise
|
|
104
|
+
* the same assertion flips between a below-floor dev box and a compliant CI).
|
|
105
|
+
*/
|
|
106
|
+
current?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The runtime gate. A microsecond no-op when Node is compliant; otherwise
|
|
110
|
+
* prints an exact, OS-/manager-aware upgrade instruction and (by default)
|
|
111
|
+
* exits non-zero.
|
|
112
|
+
*
|
|
113
|
+
* Auto mode (opt-in via `CLEO_NODE_AUTO_UPGRADE=1`) runs the install command,
|
|
114
|
+
* then STILL exits non-zero: version managers switch Node via shell shims, so
|
|
115
|
+
* a child process cannot hot-swap the interpreter already executing — the user
|
|
116
|
+
* must open a new shell and re-run. Silent toolchain mutation is deliberately
|
|
117
|
+
* never the default.
|
|
118
|
+
*
|
|
119
|
+
* @param opts - {@link EnforceOptions}.
|
|
120
|
+
* @returns The {@link NodeVersionVerdict} (for the compliant no-op path, and
|
|
121
|
+
* for tests that stub `exit`).
|
|
122
|
+
*
|
|
123
|
+
* @public
|
|
124
|
+
*/
|
|
125
|
+
export declare function enforceNodeVersion(opts?: EnforceOptions): NodeVersionVerdict;
|
|
126
|
+
//# sourceMappingURL=node-version-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version-gate.d.ts","sourceRoot":"","sources":["../src/node-version-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C,2CAA2C;AAC3C,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAItD;AAWD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAW/C;AAED,gFAAgF;AAChF,MAAM,MAAM,WAAW,GACnB,KAAK,GACL,KAAK,GACL,GAAG,GACH,OAAO,GACP,MAAM,GACN,MAAM,GACN,QAAQ,GACR,OAAO,GACP,YAAY,CAAC;AAEjB,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AA6DD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,GAAE,MAA8B,GACzC,kBAAkB,CAepB;AAED,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;IAC/B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,cAAmB,GAAG,kBAAkB,CA4ChF"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node runtime-version enforcement gate (SSoT).
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for "is the running Node new enough to run CLEO".
|
|
5
|
+
* The minimum is read from this package's own shipped `engines.node` at
|
|
6
|
+
* runtime — NOT a hardcoded constant — so bumping the floor is a one-line
|
|
7
|
+
* `package.json` edit and the gate evolves with it. A CI lint
|
|
8
|
+
* (`scripts/lint-node-engine-ssot.mjs`) keeps every workspace package's
|
|
9
|
+
* `engines.node` equal to root's, so the value the gate reads is authoritative.
|
|
10
|
+
*
|
|
11
|
+
* Lives in `@cleocode/paths` — the zero-dep leaf (only `env-paths`) that is
|
|
12
|
+
* importable BEFORE any `@cleocode/core` import. The CLI guard must run here,
|
|
13
|
+
* not at `node:sqlite` load, so an under-floor Node fails with an actionable
|
|
14
|
+
* message instead of a cryptic `ERR_UNKNOWN_BUILTIN_MODULE` / divergent-SQLite
|
|
15
|
+
* behavior. (Importing this package does NOT eagerly load `node:sqlite` — that
|
|
16
|
+
* is lazy via `createRequire`; see `cleo-paths.ts`.)
|
|
17
|
+
*
|
|
18
|
+
* Why a full-semver floor and not a major-only check: 24.13.1 satisfies
|
|
19
|
+
* `major >= 24` yet is below 24.16.0, where the bundled SQLite WAL-reset
|
|
20
|
+
* corruption fix (SQLite 3.53.0) landed. The major-only guards
|
|
21
|
+
* (`cli/index.ts`, `dependencies.ts:checkNode`) waved it through, then the
|
|
22
|
+
* persistence layer diverged from CI. This gate compares full semver.
|
|
23
|
+
*
|
|
24
|
+
* @packageDocumentation
|
|
25
|
+
* @task T11281
|
|
26
|
+
* @task T11242
|
|
27
|
+
*/
|
|
28
|
+
import { readFileSync } from 'node:fs';
|
|
29
|
+
import { createRequire } from 'node:module';
|
|
30
|
+
import { arch as osArch, platform as osPlatform } from 'node:os';
|
|
31
|
+
import { dirname, join } from 'node:path';
|
|
32
|
+
import { fileURLToPath } from 'node:url';
|
|
33
|
+
/**
|
|
34
|
+
* Last-resort floor used only when this package's `engines.node` cannot be
|
|
35
|
+
* read (e.g. a corrupted install). Kept equal to root `engines.node` by the
|
|
36
|
+
* `lint-node-engine-ssot` CI gate so it can never silently lie.
|
|
37
|
+
*/
|
|
38
|
+
export const FALLBACK_MIN_NODE = '24.16.0';
|
|
39
|
+
/**
|
|
40
|
+
* Parse the first `x.y.z` triple out of a version fragment such as
|
|
41
|
+
* `24.16.0`, `v24.16.0`, or a range like `>=24.16.0 <27`.
|
|
42
|
+
*
|
|
43
|
+
* @param raw - The version or range string.
|
|
44
|
+
* @returns The parsed {@link Semver}, or `null` when no triple is present.
|
|
45
|
+
*/
|
|
46
|
+
export function parseSemver(raw) {
|
|
47
|
+
const m = /(\d+)\.(\d+)\.(\d+)/.exec(raw.trim());
|
|
48
|
+
if (!m)
|
|
49
|
+
return null;
|
|
50
|
+
return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]) };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* `a >= b` for {@link Semver} (major, then minor, then patch).
|
|
54
|
+
*/
|
|
55
|
+
function gte(a, b) {
|
|
56
|
+
if (a.major !== b.major)
|
|
57
|
+
return a.major > b.major;
|
|
58
|
+
if (a.minor !== b.minor)
|
|
59
|
+
return a.minor > b.minor;
|
|
60
|
+
return a.patch >= b.patch;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read the minimum Node version from this package's shipped `engines.node`
|
|
64
|
+
* (the SSoT). Falls back to {@link FALLBACK_MIN_NODE} when the manifest is
|
|
65
|
+
* unreadable or declares no parseable version.
|
|
66
|
+
*
|
|
67
|
+
* @returns A normalized `major.minor.patch` string.
|
|
68
|
+
*
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
export function getRequiredNodeVersion() {
|
|
72
|
+
try {
|
|
73
|
+
const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
|
|
74
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
75
|
+
const parsed = parseSemver(pkg.engines?.node ?? '');
|
|
76
|
+
return parsed ? `${parsed.major}.${parsed.minor}.${parsed.patch}` : FALLBACK_MIN_NODE;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return FALLBACK_MIN_NODE;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Build OS- and manager-aware upgrade hints from environment + platform ONLY
|
|
84
|
+
* (no `child_process` spawns), so the compliant fast-path stays a no-op.
|
|
85
|
+
*
|
|
86
|
+
* @param required - The required Node version (e.g. `24.16.0`).
|
|
87
|
+
* @param platform - The current `process.platform`.
|
|
88
|
+
*/
|
|
89
|
+
function upgradeHints(required, platform) {
|
|
90
|
+
const hints = [];
|
|
91
|
+
const e = process.env;
|
|
92
|
+
if (e['FNM_DIR'] || e['FNM_MULTISHELL_PATH']) {
|
|
93
|
+
hints.push({
|
|
94
|
+
manager: 'fnm',
|
|
95
|
+
command: `fnm install ${required} && fnm use ${required} && fnm default ${required}`,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (e['NVM_DIR']) {
|
|
99
|
+
hints.push({
|
|
100
|
+
manager: 'nvm',
|
|
101
|
+
command: `nvm install ${required} && nvm alias default ${required}`,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (e['VOLTA_HOME']) {
|
|
105
|
+
hints.push({ manager: 'volta', command: `volta install node@${required}` });
|
|
106
|
+
}
|
|
107
|
+
if (e['ASDF_DIR'] || e['ASDF_DATA_DIR']) {
|
|
108
|
+
hints.push({
|
|
109
|
+
manager: 'asdf',
|
|
110
|
+
command: `asdf install nodejs ${required} && asdf global nodejs ${required}`,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
// Platform fallbacks when no manager env is detected.
|
|
114
|
+
if (hints.length === 0) {
|
|
115
|
+
if (platform === 'win32') {
|
|
116
|
+
hints.push({ manager: 'winget', command: 'winget install OpenJS.NodeJS' });
|
|
117
|
+
hints.push({ manager: 'choco', command: `choco upgrade nodejs --version=${required}` });
|
|
118
|
+
}
|
|
119
|
+
else if (platform === 'darwin') {
|
|
120
|
+
hints.push({ manager: 'brew', command: 'brew upgrade node' });
|
|
121
|
+
hints.push({
|
|
122
|
+
manager: 'fnm',
|
|
123
|
+
command: `curl -fsSL https://fnm.vercel.app/install | bash && fnm install ${required}`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
hints.push({
|
|
128
|
+
manager: 'fnm',
|
|
129
|
+
command: `curl -fsSL https://fnm.vercel.app/install | bash && fnm install ${required}`,
|
|
130
|
+
});
|
|
131
|
+
hints.push({
|
|
132
|
+
manager: 'nodesource',
|
|
133
|
+
command: '# see https://github.com/nodesource/distributions',
|
|
134
|
+
note: 'system-wide install',
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return hints;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Evaluate the running Node against the required floor. Pure and
|
|
142
|
+
* side-effect-free (no `process.exit`, no I/O beyond the SSoT manifest read) —
|
|
143
|
+
* safe to call from `doctor`/`health` and unit tests.
|
|
144
|
+
*
|
|
145
|
+
* @param currentRaw - The Node version to evaluate. Defaults to
|
|
146
|
+
* `process.versions.node`.
|
|
147
|
+
* @returns The {@link NodeVersionVerdict}.
|
|
148
|
+
*
|
|
149
|
+
* @public
|
|
150
|
+
*/
|
|
151
|
+
export function evaluateNodeVersion(currentRaw = process.versions.node) {
|
|
152
|
+
const required = getRequiredNodeVersion();
|
|
153
|
+
const cur = parseSemver(currentRaw);
|
|
154
|
+
const req = parseSemver(required) ?? parseSemver(FALLBACK_MIN_NODE);
|
|
155
|
+
const platform = osPlatform();
|
|
156
|
+
// `req` is non-null: FALLBACK_MIN_NODE is a valid triple by construction.
|
|
157
|
+
const compliant = cur !== null && req !== null && gte(cur, req);
|
|
158
|
+
return {
|
|
159
|
+
compliant,
|
|
160
|
+
current: currentRaw,
|
|
161
|
+
required,
|
|
162
|
+
platform,
|
|
163
|
+
arch: osArch(),
|
|
164
|
+
hints: compliant ? [] : upgradeHints(required, platform),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The runtime gate. A microsecond no-op when Node is compliant; otherwise
|
|
169
|
+
* prints an exact, OS-/manager-aware upgrade instruction and (by default)
|
|
170
|
+
* exits non-zero.
|
|
171
|
+
*
|
|
172
|
+
* Auto mode (opt-in via `CLEO_NODE_AUTO_UPGRADE=1`) runs the install command,
|
|
173
|
+
* then STILL exits non-zero: version managers switch Node via shell shims, so
|
|
174
|
+
* a child process cannot hot-swap the interpreter already executing — the user
|
|
175
|
+
* must open a new shell and re-run. Silent toolchain mutation is deliberately
|
|
176
|
+
* never the default.
|
|
177
|
+
*
|
|
178
|
+
* @param opts - {@link EnforceOptions}.
|
|
179
|
+
* @returns The {@link NodeVersionVerdict} (for the compliant no-op path, and
|
|
180
|
+
* for tests that stub `exit`).
|
|
181
|
+
*
|
|
182
|
+
* @public
|
|
183
|
+
*/
|
|
184
|
+
export function enforceNodeVersion(opts = {}) {
|
|
185
|
+
const verdict = evaluateNodeVersion(opts.current);
|
|
186
|
+
if (verdict.compliant)
|
|
187
|
+
return verdict; // fast path — the common case
|
|
188
|
+
const write = opts.write ?? ((s) => void process.stderr.write(s));
|
|
189
|
+
const exit = opts.exit ?? ((c) => process.exit(c));
|
|
190
|
+
const mode = opts.mode ?? (process.env['CLEO_NODE_AUTO_UPGRADE'] === '1' ? 'auto' : 'enforce');
|
|
191
|
+
const primary = verdict.hints[0]?.command ?? `# install Node >= ${verdict.required}`;
|
|
192
|
+
const extra = verdict.hints
|
|
193
|
+
.slice(1)
|
|
194
|
+
.map((h) => ` (${h.manager}) ${h.command}\n`)
|
|
195
|
+
.join('');
|
|
196
|
+
write(`\nError: cleo requires Node.js >= ${verdict.required}\n` +
|
|
197
|
+
`You are running Node ${verdict.current} (${verdict.platform}/${verdict.arch}).\n\n` +
|
|
198
|
+
`Node ${verdict.required} bundles the SQLite WAL-reset corruption fix CLEO's\n` +
|
|
199
|
+
`persistence layer (node:sqlite, zero native deps) depends on. Older 24.x\n` +
|
|
200
|
+
`builds pass a major-only check but diverge at runtime (e.g. sqlite_master\n` +
|
|
201
|
+
`DEFENSIVE-mode handling), causing local results to differ from CI.\n\n` +
|
|
202
|
+
`Update to proceed:\n ${primary}\n\n` +
|
|
203
|
+
(extra ? `Other options:\n${extra}\n` : ''));
|
|
204
|
+
if (mode === 'warn')
|
|
205
|
+
return verdict;
|
|
206
|
+
if (mode === 'auto') {
|
|
207
|
+
// Deferred require keeps child_process off the compliant fast-path. A
|
|
208
|
+
// version-manager install mutates the SHELL, not this process, so we run it
|
|
209
|
+
// then still exit non-zero below asking for a fresh shell + re-run.
|
|
210
|
+
try {
|
|
211
|
+
const req = createRequire(import.meta.url);
|
|
212
|
+
const { execSync } = req('node:child_process');
|
|
213
|
+
write(`Attempting: ${primary}\n`);
|
|
214
|
+
// execSync runs through a shell by default, so compound `&&` commands work.
|
|
215
|
+
execSync(primary, { stdio: 'inherit' });
|
|
216
|
+
write(`\nInstalled Node ${verdict.required}. Open a NEW shell and re-run cleo.\n`);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
write('\nAuto-upgrade failed — run the command above manually.\n');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return exit(1);
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=node-version-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version-gate.js","sourceRoot":"","sources":["../src/node-version-gate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/paths",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.130",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "CLEO XDG/env-paths SSoT — createPlatformPathsResolver factory, cleo-bound platform paths, project hash + worktree root primitives, isAbsolutePath. Zero-dep leaf package consumed by core, worktree, brain, adapters, and caamp.",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"platform"
|
|
25
25
|
],
|
|
26
26
|
"engines": {
|
|
27
|
-
"node": ">=24.
|
|
27
|
+
"node": ">=24.16.0"
|
|
28
28
|
},
|
|
29
29
|
"author": "CLEO Code <hello@cleocode.dev>",
|
|
30
30
|
"license": "MIT",
|