@cleocode/paths 2026.5.123 → 2026.5.125
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 +96 -0
- package/dist/cleo-paths.d.ts.map +1 -1
- package/dist/cleo-paths.js +242 -1
- package/dist/cleo-paths.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/worktree-paths.d.ts +4 -0
- package/dist/worktree-paths.d.ts.map +1 -1
- package/dist/worktree-paths.js +15 -1
- package/dist/worktree-paths.js.map +1 -1
- package/package.json +1 -1
package/dist/cleo-paths.d.ts
CHANGED
|
@@ -111,6 +111,102 @@ export declare function getCanonicalTemplatesTildePath(): string;
|
|
|
111
111
|
* @public
|
|
112
112
|
*/
|
|
113
113
|
export declare function resolveLegacyCleoDir(override?: string): string;
|
|
114
|
+
/**
|
|
115
|
+
* Result of {@link resolveProjectByCwd} — the project identity resolved
|
|
116
|
+
* from walking up from a working directory.
|
|
117
|
+
*
|
|
118
|
+
* @public
|
|
119
|
+
/** Result of {@link resolveProjectByCwd} — the project identity resolved from walking up from a working directory. */
|
|
120
|
+
export interface ResolvedProject {
|
|
121
|
+
/** Stable canonical project ID (12-hex-char SHA-256 of git-root|name|remote). */
|
|
122
|
+
projectId: string;
|
|
123
|
+
/** Absolute realpath to the project root directory. */
|
|
124
|
+
projectRoot: string;
|
|
125
|
+
/** The legacy UUID from project-info.json, if present. */
|
|
126
|
+
legacyUUID?: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Compute the canonical project ID for a given repository path (T9149/T11023).
|
|
130
|
+
*
|
|
131
|
+
* Algorithm:
|
|
132
|
+
* 1. Resolve `repoPath` to its `realpath` (resolves symlinks, normalises mounts).
|
|
133
|
+
* 2. Detect the git root via `git rev-parse --show-toplevel` (falls back to realpath).
|
|
134
|
+
* 3. Read `.cleo/project-info.json` name (optional).
|
|
135
|
+
* 4. Read `git remote get-url origin` (optional).
|
|
136
|
+
* 5. SHA-256 of `<gitRoot>|<projectName>|<remoteUrl>`, first 12 hex chars.
|
|
137
|
+
*
|
|
138
|
+
* This ensures `/mnt/projects/X` and `/workspace/X` (same git root,
|
|
139
|
+
* same remote) produce the same ID.
|
|
140
|
+
*
|
|
141
|
+
* @param repoPath - Absolute path to the project root.
|
|
142
|
+
* @returns The 12-hex-char canonical project ID.
|
|
143
|
+
*
|
|
144
|
+
* @task T11023
|
|
145
|
+
* @task T9149
|
|
146
|
+
*/
|
|
147
|
+
export declare function computeCanonicalProjectId(repoPath: string): string;
|
|
148
|
+
/**
|
|
149
|
+
* Compute the legacy base64url(path) ID for a given path.
|
|
150
|
+
* This is the old algorithm used before T9149 W5.
|
|
151
|
+
*/
|
|
152
|
+
export declare function legacyProjectId(repoPath: string): string;
|
|
153
|
+
/**
|
|
154
|
+
* Walk up from `cwd` (or `process.cwd()`) looking for `.cleo/project-info.json`
|
|
155
|
+
* and return the project identity if found.
|
|
156
|
+
*
|
|
157
|
+
* This replaces the ancestor-walk pattern in `getCleoDirAbsolute` with a
|
|
158
|
+
* projectId-aware lookup. Instead of resolving a `.cleo/` directory via
|
|
159
|
+
* git-root heuristics, it reads the stable `projectId` from the canonical
|
|
160
|
+
* project-info file — enabling move-safe project identification.
|
|
161
|
+
*
|
|
162
|
+
* **Cross-mount divergence (T11023):** Uses `realpathSync` to normalize
|
|
163
|
+
* bind-mounts and symlinks so the same repo at `/mnt/projects/X` and
|
|
164
|
+
* `/workspace/X` resolves to the same `projectRoot`. The `projectId` is
|
|
165
|
+
* the T9149 canonical 12-hex-char SHA-256 fingerprint of git-root + name
|
|
166
|
+
* + remote URL, which is also mount-invariant.
|
|
167
|
+
*
|
|
168
|
+
* @param cwd - Optional working directory to start the ancestor walk from.
|
|
169
|
+
* Defaults to `process.cwd()`.
|
|
170
|
+
* @returns The resolved project identity, or `null` if no CLEO project is
|
|
171
|
+
* found anywhere in the ancestor chain.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const project = resolveProjectByCwd('/repo/packages/core');
|
|
176
|
+
* // { projectId: 'a1b2c3d4e5f6', projectRoot: '/repo' }
|
|
177
|
+
*
|
|
178
|
+
* const notFound = resolveProjectByCwd('/tmp/empty');
|
|
179
|
+
* // null
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @public
|
|
183
|
+
* @task T11008
|
|
184
|
+
* @task T11023
|
|
185
|
+
*/
|
|
186
|
+
export declare function resolveProjectByCwd(cwd?: string): ResolvedProject | null;
|
|
187
|
+
/**
|
|
188
|
+
* Resolve the canonical `.cleo` directory for a project given its `projectId`.
|
|
189
|
+
*
|
|
190
|
+
* Looks up the project in the global `nexus.db` registry (`project_registry`
|
|
191
|
+
* table) to find the project's root path, then returns the `.cleo/` directory
|
|
192
|
+
* under that root.
|
|
193
|
+
*
|
|
194
|
+
* **Legacy ID support (T11023 AC4):** If the `projectId` is not found in
|
|
195
|
+
* `project_registry`, also checks the `project_id_aliases` table for a
|
|
196
|
+
* legacy→canonical mapping before returning `null`.
|
|
197
|
+
*
|
|
198
|
+
* This enables cross-project lookups: given a stable project ID, resolve where
|
|
199
|
+
* that project lives on disk without walking from a working directory.
|
|
200
|
+
*
|
|
201
|
+
* @param projectId - The project ID to look up. Can be a canonical 12-hex-char
|
|
202
|
+
* ID, a legacy UUID, or a legacy base64url(path) ID.
|
|
203
|
+
* @returns Absolute path to the `.cleo/` directory, or `null` if the
|
|
204
|
+
* projectId is not found in the nexus registry (or its alias table).
|
|
205
|
+
*
|
|
206
|
+
* @task T11008
|
|
207
|
+
* @task T11023
|
|
208
|
+
*/
|
|
209
|
+
export declare function resolveCanonicalCleoDir(projectId: string): string | null;
|
|
114
210
|
/**
|
|
115
211
|
* Invalidate the cached CLEO system info snapshot. Use in tests after
|
|
116
212
|
* mutating `CLEO_HOME` or related env vars.
|
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;AAQH,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAM7B;;;;;;;;;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;;;;;uHAKuH;AACvH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuDD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWlE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA8CxE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiExE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
|
package/dist/cleo-paths.js
CHANGED
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @task T1883
|
|
10
10
|
*/
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
12
|
+
import { createHash } from 'node:crypto';
|
|
13
|
+
import { existsSync, readFileSync, realpathSync } from 'node:fs';
|
|
11
14
|
import { homedir } from 'node:os';
|
|
12
|
-
import { join } from 'node:path';
|
|
15
|
+
import { dirname, join, resolve } from 'node:path';
|
|
16
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
13
17
|
import { createPlatformPathsResolver, } from './platform-paths.js';
|
|
14
18
|
const TEMPLATES_SUBDIR = 'templates';
|
|
15
19
|
const cleoResolver = createPlatformPathsResolver('cleo', 'CLEO_HOME', 'CLEO_CONFIG_HOME');
|
|
@@ -145,6 +149,243 @@ export function resolveLegacyCleoDir(override) {
|
|
|
145
149
|
return override;
|
|
146
150
|
return join(homedir(), '.cleo');
|
|
147
151
|
}
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Canonical project ID computation (T11023 — cross-mount divergence)
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
/**
|
|
156
|
+
* Synchronously find the git root for a given directory.
|
|
157
|
+
* Returns `null` if the directory is not inside a git repo.
|
|
158
|
+
*/
|
|
159
|
+
function _findGitRootSync(fromPath) {
|
|
160
|
+
try {
|
|
161
|
+
const stdout = execFileSync('git', ['rev-parse', '--show-toplevel'], {
|
|
162
|
+
cwd: resolve(fromPath),
|
|
163
|
+
encoding: 'utf-8',
|
|
164
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
165
|
+
});
|
|
166
|
+
return resolve(stdout.trim());
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Synchronously find the primary git remote URL (origin fetch URL).
|
|
174
|
+
* Returns `null` when there are no remotes or git is unavailable.
|
|
175
|
+
*/
|
|
176
|
+
function _findGitRemoteUrlSync(fromPath) {
|
|
177
|
+
try {
|
|
178
|
+
const stdout = execFileSync('git', ['remote', 'get-url', 'origin'], {
|
|
179
|
+
cwd: resolve(fromPath),
|
|
180
|
+
encoding: 'utf-8',
|
|
181
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
182
|
+
});
|
|
183
|
+
const url = stdout.trim();
|
|
184
|
+
return url || null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Read the project name from `.cleo/project-info.json` (if present).
|
|
192
|
+
* Non-fatal on any I/O or parse error.
|
|
193
|
+
*/
|
|
194
|
+
function _readProjectInfoName(repoRoot) {
|
|
195
|
+
try {
|
|
196
|
+
const raw = readFileSync(join(repoRoot, '.cleo', 'project-info.json'), 'utf-8');
|
|
197
|
+
const parsed = JSON.parse(raw);
|
|
198
|
+
return typeof parsed.name === 'string' ? parsed.name : undefined;
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Compute the canonical project ID for a given repository path (T9149/T11023).
|
|
206
|
+
*
|
|
207
|
+
* Algorithm:
|
|
208
|
+
* 1. Resolve `repoPath` to its `realpath` (resolves symlinks, normalises mounts).
|
|
209
|
+
* 2. Detect the git root via `git rev-parse --show-toplevel` (falls back to realpath).
|
|
210
|
+
* 3. Read `.cleo/project-info.json` name (optional).
|
|
211
|
+
* 4. Read `git remote get-url origin` (optional).
|
|
212
|
+
* 5. SHA-256 of `<gitRoot>|<projectName>|<remoteUrl>`, first 12 hex chars.
|
|
213
|
+
*
|
|
214
|
+
* This ensures `/mnt/projects/X` and `/workspace/X` (same git root,
|
|
215
|
+
* same remote) produce the same ID.
|
|
216
|
+
*
|
|
217
|
+
* @param repoPath - Absolute path to the project root.
|
|
218
|
+
* @returns The 12-hex-char canonical project ID.
|
|
219
|
+
*
|
|
220
|
+
* @task T11023
|
|
221
|
+
* @task T9149
|
|
222
|
+
*/
|
|
223
|
+
export function computeCanonicalProjectId(repoPath) {
|
|
224
|
+
const realRepoPath = realpathSync(resolve(repoPath));
|
|
225
|
+
const gitRoot = _findGitRootSync(realRepoPath);
|
|
226
|
+
const effectiveRoot = gitRoot ?? realRepoPath;
|
|
227
|
+
const remoteUrl = gitRoot ? _findGitRemoteUrlSync(gitRoot) : null;
|
|
228
|
+
const projectName = _readProjectInfoName(effectiveRoot);
|
|
229
|
+
const fingerprint = [effectiveRoot, projectName ?? '', remoteUrl ?? ''].join('|');
|
|
230
|
+
return createHash('sha256').update(fingerprint).digest('hex').substring(0, 12);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Compute the legacy base64url(path) ID for a given path.
|
|
234
|
+
* This is the old algorithm used before T9149 W5.
|
|
235
|
+
*/
|
|
236
|
+
export function legacyProjectId(repoPath) {
|
|
237
|
+
return Buffer.from(repoPath).toString('base64url').slice(0, 32);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Walk up from `cwd` (or `process.cwd()`) looking for `.cleo/project-info.json`
|
|
241
|
+
* and return the project identity if found.
|
|
242
|
+
*
|
|
243
|
+
* This replaces the ancestor-walk pattern in `getCleoDirAbsolute` with a
|
|
244
|
+
* projectId-aware lookup. Instead of resolving a `.cleo/` directory via
|
|
245
|
+
* git-root heuristics, it reads the stable `projectId` from the canonical
|
|
246
|
+
* project-info file — enabling move-safe project identification.
|
|
247
|
+
*
|
|
248
|
+
* **Cross-mount divergence (T11023):** Uses `realpathSync` to normalize
|
|
249
|
+
* bind-mounts and symlinks so the same repo at `/mnt/projects/X` and
|
|
250
|
+
* `/workspace/X` resolves to the same `projectRoot`. The `projectId` is
|
|
251
|
+
* the T9149 canonical 12-hex-char SHA-256 fingerprint of git-root + name
|
|
252
|
+
* + remote URL, which is also mount-invariant.
|
|
253
|
+
*
|
|
254
|
+
* @param cwd - Optional working directory to start the ancestor walk from.
|
|
255
|
+
* Defaults to `process.cwd()`.
|
|
256
|
+
* @returns The resolved project identity, or `null` if no CLEO project is
|
|
257
|
+
* found anywhere in the ancestor chain.
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const project = resolveProjectByCwd('/repo/packages/core');
|
|
262
|
+
* // { projectId: 'a1b2c3d4e5f6', projectRoot: '/repo' }
|
|
263
|
+
*
|
|
264
|
+
* const notFound = resolveProjectByCwd('/tmp/empty');
|
|
265
|
+
* // null
|
|
266
|
+
* ```
|
|
267
|
+
*
|
|
268
|
+
* @public
|
|
269
|
+
* @task T11008
|
|
270
|
+
* @task T11023
|
|
271
|
+
*/
|
|
272
|
+
export function resolveProjectByCwd(cwd) {
|
|
273
|
+
const start = resolve(cwd ?? process.cwd());
|
|
274
|
+
let current = start;
|
|
275
|
+
while (true) {
|
|
276
|
+
const infoPath = join(current, '.cleo', 'project-info.json');
|
|
277
|
+
if (existsSync(infoPath)) {
|
|
278
|
+
try {
|
|
279
|
+
const raw = readFileSync(infoPath, 'utf-8');
|
|
280
|
+
const data = JSON.parse(raw);
|
|
281
|
+
if (typeof data.projectId === 'string' && data.projectId.length > 0) {
|
|
282
|
+
// T11023: Normalize projectRoot via realpathSync to handle cross-mount
|
|
283
|
+
// divergence — same repo at /mnt/projects/X and /workspace/X resolves
|
|
284
|
+
// to the same real path (AC2, AC3).
|
|
285
|
+
let realRoot;
|
|
286
|
+
try {
|
|
287
|
+
realRoot = realpathSync(current);
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
// realpathSync fails on nonexistent paths — fall back to resolved path
|
|
291
|
+
realRoot = current;
|
|
292
|
+
}
|
|
293
|
+
// T11023: Compute canonical projectId using T9149 algorithm
|
|
294
|
+
// (git-root + realpath fingerprint) for mount-invariant identity (AC1).
|
|
295
|
+
const canonicalId = computeCanonicalProjectId(realRoot);
|
|
296
|
+
return {
|
|
297
|
+
projectId: canonicalId,
|
|
298
|
+
projectRoot: realRoot,
|
|
299
|
+
legacyUUID: data.projectId,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// Corrupt or unparseable project-info.json — keep walking up.
|
|
305
|
+
// A higher ancestor may have a valid one.
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const parent = dirname(current);
|
|
309
|
+
if (parent === current)
|
|
310
|
+
break; // Reached filesystem root
|
|
311
|
+
current = parent;
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Resolve the canonical `.cleo` directory for a project given its `projectId`.
|
|
317
|
+
*
|
|
318
|
+
* Looks up the project in the global `nexus.db` registry (`project_registry`
|
|
319
|
+
* table) to find the project's root path, then returns the `.cleo/` directory
|
|
320
|
+
* under that root.
|
|
321
|
+
*
|
|
322
|
+
* **Legacy ID support (T11023 AC4):** If the `projectId` is not found in
|
|
323
|
+
* `project_registry`, also checks the `project_id_aliases` table for a
|
|
324
|
+
* legacy→canonical mapping before returning `null`.
|
|
325
|
+
*
|
|
326
|
+
* This enables cross-project lookups: given a stable project ID, resolve where
|
|
327
|
+
* that project lives on disk without walking from a working directory.
|
|
328
|
+
*
|
|
329
|
+
* @param projectId - The project ID to look up. Can be a canonical 12-hex-char
|
|
330
|
+
* ID, a legacy UUID, or a legacy base64url(path) ID.
|
|
331
|
+
* @returns Absolute path to the `.cleo/` directory, or `null` if the
|
|
332
|
+
* projectId is not found in the nexus registry (or its alias table).
|
|
333
|
+
*
|
|
334
|
+
* @task T11008
|
|
335
|
+
* @task T11023
|
|
336
|
+
*/
|
|
337
|
+
export function resolveCanonicalCleoDir(projectId) {
|
|
338
|
+
const cleoHome = getCleoHome();
|
|
339
|
+
const nexusDbPath = join(cleoHome, 'nexus.db');
|
|
340
|
+
if (!existsSync(nexusDbPath))
|
|
341
|
+
return null;
|
|
342
|
+
let db;
|
|
343
|
+
try {
|
|
344
|
+
db = new DatabaseSync(nexusDbPath, { readOnly: true });
|
|
345
|
+
// Try direct project_registry lookup first.
|
|
346
|
+
const directStmt = db.prepare('SELECT project_path FROM project_registry WHERE project_id = ? LIMIT 1');
|
|
347
|
+
const directRow = directStmt.get(projectId);
|
|
348
|
+
if (directRow &&
|
|
349
|
+
typeof directRow.project_path === 'string' &&
|
|
350
|
+
directRow.project_path.length > 0) {
|
|
351
|
+
return join(directRow.project_path, '.cleo');
|
|
352
|
+
}
|
|
353
|
+
// T11023 AC4: Fall back to project_id_aliases for legacy ID resolution.
|
|
354
|
+
// Legacy base64url(path) IDs and old UUIDs are mapped to canonical IDs
|
|
355
|
+
// in the aliases table. Try resolving the input as a legacy ID first,
|
|
356
|
+
// then look up the canonical ID.
|
|
357
|
+
try {
|
|
358
|
+
const aliasStmt = db.prepare('SELECT canonical_id FROM project_id_aliases WHERE legacy_id = ? LIMIT 1');
|
|
359
|
+
const aliasRow = aliasStmt.get(projectId);
|
|
360
|
+
if (aliasRow &&
|
|
361
|
+
typeof aliasRow.canonical_id === 'string' &&
|
|
362
|
+
aliasRow.canonical_id.length > 0) {
|
|
363
|
+
// Resolved a legacy alias — look up the canonical ID.
|
|
364
|
+
const canonicalRow = directStmt.get(aliasRow.canonical_id);
|
|
365
|
+
if (canonicalRow &&
|
|
366
|
+
typeof canonicalRow.project_path === 'string' &&
|
|
367
|
+
canonicalRow.project_path.length > 0) {
|
|
368
|
+
return join(canonicalRow.project_path, '.cleo');
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
// project_id_aliases table may not exist yet (pre-migration) — non-fatal.
|
|
374
|
+
}
|
|
375
|
+
return null;
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
finally {
|
|
381
|
+
try {
|
|
382
|
+
db?.close();
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
// Best-effort close
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
148
389
|
/**
|
|
149
390
|
* Invalidate the cached CLEO system info snapshot. Use in tests after
|
|
150
391
|
* mutating `CLEO_HOME` or related env vars.
|
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,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
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
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* - {@link createPlatformPathsResolver} — generic factory bindable to any app
|
|
11
11
|
* - CLEO-bound helpers: {@link getCleoHome}, {@link getCleoPlatformPaths},
|
|
12
12
|
* {@link getCleoSystemInfo}, {@link getCleoTemplatesTildePath}
|
|
13
|
+
* - Project resolution: {@link resolveProjectByCwd}, {@link resolveCanonicalCleoDir}
|
|
13
14
|
* - Worktree primitives: {@link computeProjectHash},
|
|
14
15
|
* {@link resolveWorktreeRootForHash}, {@link resolveTaskWorktreePath},
|
|
15
16
|
* {@link getCleoWorktreesRoot}, {@link resolveWorktreeIndexPath}
|
|
@@ -17,9 +18,10 @@
|
|
|
17
18
|
*
|
|
18
19
|
* @packageDocumentation
|
|
19
20
|
* @task T1883
|
|
21
|
+
* @task T11008
|
|
20
22
|
*/
|
|
21
23
|
export { isAbsolutePath } from './abs-path.js';
|
|
22
|
-
export { _resetCleoPlatformPathsCache, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, resolveLegacyCleoDir, } from './cleo-paths.js';
|
|
24
|
+
export { _resetCleoPlatformPathsCache, computeCanonicalProjectId, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, legacyProjectId, type ResolvedProject, resolveCanonicalCleoDir, resolveLegacyCleoDir, resolveProjectByCwd, } from './cleo-paths.js';
|
|
23
25
|
export { createPlatformPathsResolver, type PlatformPaths, type PlatformPathsResolver, type SystemInfo, } from './platform-paths.js';
|
|
24
26
|
export { computeProjectHash, getCleoWorktreesRoot, resolveTaskWorktreePath, resolveWorktreeIndexPath, resolveWorktreeRootForHash, } from './worktree-paths.js';
|
|
25
27
|
//# 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
|
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* - {@link createPlatformPathsResolver} — generic factory bindable to any app
|
|
11
11
|
* - CLEO-bound helpers: {@link getCleoHome}, {@link getCleoPlatformPaths},
|
|
12
12
|
* {@link getCleoSystemInfo}, {@link getCleoTemplatesTildePath}
|
|
13
|
+
* - Project resolution: {@link resolveProjectByCwd}, {@link resolveCanonicalCleoDir}
|
|
13
14
|
* - Worktree primitives: {@link computeProjectHash},
|
|
14
15
|
* {@link resolveWorktreeRootForHash}, {@link resolveTaskWorktreePath},
|
|
15
16
|
* {@link getCleoWorktreesRoot}, {@link resolveWorktreeIndexPath}
|
|
@@ -17,9 +18,10 @@
|
|
|
17
18
|
*
|
|
18
19
|
* @packageDocumentation
|
|
19
20
|
* @task T1883
|
|
21
|
+
* @task T11008
|
|
20
22
|
*/
|
|
21
23
|
export { isAbsolutePath } from './abs-path.js';
|
|
22
|
-
export { _resetCleoPlatformPathsCache, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, resolveLegacyCleoDir, } from './cleo-paths.js';
|
|
24
|
+
export { _resetCleoPlatformPathsCache, computeCanonicalProjectId, getCanonicalTemplatesTildePath, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, legacyProjectId, resolveCanonicalCleoDir, resolveLegacyCleoDir, resolveProjectByCwd, } from './cleo-paths.js';
|
|
23
25
|
export { createPlatformPathsResolver, } from './platform-paths.js';
|
|
24
26
|
export { computeProjectHash, getCleoWorktreesRoot, resolveTaskWorktreePath, resolveWorktreeIndexPath, resolveWorktreeRootForHash, } from './worktree-paths.js';
|
|
25
27
|
//# 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
|
|
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"}
|
package/dist/worktree-paths.d.ts
CHANGED
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
* the historical implementation in `branch-lock.ts#resolveAgentWorktreeRoot`
|
|
22
22
|
* (the root cause of the duplicated logic this package consolidates).
|
|
23
23
|
*
|
|
24
|
+
* **Cross-mount normalization (T11023 AC3):** The input path is resolved
|
|
25
|
+
* through `realpathSync` before hashing so that different mount points
|
|
26
|
+
* (/mnt/projects/X vs /workspace/X) produce the same hash.
|
|
27
|
+
*
|
|
24
28
|
* @param projectRoot - Absolute path to the project root.
|
|
25
29
|
* @returns 16-character lowercase hex string.
|
|
26
30
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree-paths.d.ts","sourceRoot":"","sources":["../src/worktree-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"worktree-paths.d.ts","sourceRoot":"","sources":["../src/worktree-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA2BH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAU9D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAGR;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpE"}
|
package/dist/worktree-paths.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* @task T9802
|
|
16
16
|
*/
|
|
17
17
|
import { createHash } from 'node:crypto';
|
|
18
|
+
import { realpathSync } from 'node:fs';
|
|
18
19
|
import { join } from 'node:path';
|
|
19
20
|
import { getCleoHome } from './cleo-paths.js';
|
|
20
21
|
const WORKTREES_SUBDIR = 'worktrees';
|
|
@@ -42,13 +43,26 @@ function joinSegments(base, ...parts) {
|
|
|
42
43
|
* the historical implementation in `branch-lock.ts#resolveAgentWorktreeRoot`
|
|
43
44
|
* (the root cause of the duplicated logic this package consolidates).
|
|
44
45
|
*
|
|
46
|
+
* **Cross-mount normalization (T11023 AC3):** The input path is resolved
|
|
47
|
+
* through `realpathSync` before hashing so that different mount points
|
|
48
|
+
* (/mnt/projects/X vs /workspace/X) produce the same hash.
|
|
49
|
+
*
|
|
45
50
|
* @param projectRoot - Absolute path to the project root.
|
|
46
51
|
* @returns 16-character lowercase hex string.
|
|
47
52
|
*
|
|
48
53
|
* @public
|
|
49
54
|
*/
|
|
50
55
|
export function computeProjectHash(projectRoot) {
|
|
51
|
-
|
|
56
|
+
// T11023: Normalize via realpath to handle cross-mount divergence.
|
|
57
|
+
// realpathSync throws on nonexistent paths — fall back to raw path.
|
|
58
|
+
let normalized;
|
|
59
|
+
try {
|
|
60
|
+
normalized = realpathSync(projectRoot);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
normalized = projectRoot;
|
|
64
|
+
}
|
|
65
|
+
return createHash('sha256').update(normalized).digest('hex').slice(0, PROJECT_HASH_LENGTH);
|
|
52
66
|
}
|
|
53
67
|
/**
|
|
54
68
|
* Resolve the worktrees root directory for a given project hash.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree-paths.js","sourceRoot":"","sources":["../src/worktree-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,gBAAgB,GAAG,WAAW,CAAC;AACrC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B;;;;;;;;;GASG;AACH,SAAS,YAAY,CAAC,IAAY,EAAE,GAAG,KAAe;IACpD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"worktree-paths.js","sourceRoot":"","sources":["../src/worktree-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,gBAAgB,GAAG,WAAW,CAAC;AACrC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B;;;;;;;;;GASG;AACH,SAAS,YAAY,CAAC,IAAY,EAAE,GAAG,KAAe;IACpD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,mEAAmE;IACnE,oEAAoE;IACpE,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,WAAW,CAAC;IAC3B,CAAC;IACD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAC7F,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAAmB,EAAE,YAAqB;IACnF,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,OAAO,YAAY,CAAC,WAAW,EAAE,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CACrC,WAAmB,EACnB,MAAc,EACd,YAAqB;IAErB,MAAM,IAAI,GAAG,0BAA0B,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACnE,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,YAAY,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAmB;IAC1D,OAAO,YAAY,CAAC,WAAW,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC9D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/paths",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.125",
|
|
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.",
|