@cleocode/paths 2026.5.26
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/LICENSE +21 -0
- package/dist/abs-path.d.ts +28 -0
- package/dist/abs-path.d.ts.map +1 -0
- package/dist/abs-path.js +37 -0
- package/dist/abs-path.js.map +1 -0
- package/dist/cleo-paths.d.ts +66 -0
- package/dist/cleo-paths.d.ts.map +1 -0
- package/dist/cleo-paths.js +86 -0
- package/dist/cleo-paths.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/platform-paths.d.ts +113 -0
- package/dist/platform-paths.d.ts.map +1 -0
- package/dist/platform-paths.js +97 -0
- package/dist/platform-paths.js.map +1 -0
- package/dist/worktree-paths.d.ts +64 -0
- package/dist/worktree-paths.d.ts.map +1 -0
- package/dist/worktree-paths.js +79 -0
- package/dist/worktree-paths.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CLEO Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform absolute path detection.
|
|
3
|
+
*
|
|
4
|
+
* Recognises POSIX absolute paths (`/...`), Windows drive letters (`C:\...`,
|
|
5
|
+
* `D:/...`), and UNC paths (`\\server\share`). Used in path-resolution code
|
|
6
|
+
* that needs to short-circuit when given an already-absolute path without
|
|
7
|
+
* importing the heavier `node:path#isAbsolute`.
|
|
8
|
+
*
|
|
9
|
+
* @task T1883
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Check if a path is absolute on any supported platform.
|
|
13
|
+
*
|
|
14
|
+
* @param path - Filesystem path to check.
|
|
15
|
+
* @returns `true` for POSIX absolute, Windows drive-rooted, or UNC paths.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* isAbsolutePath('/usr/bin'); // true
|
|
20
|
+
* isAbsolutePath('C:\\Users'); // true
|
|
21
|
+
* isAbsolutePath('\\\\srv\\sh'); // true
|
|
22
|
+
* isAbsolutePath('./relative'); // false
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare function isAbsolutePath(path: string): boolean;
|
|
28
|
+
//# sourceMappingURL=abs-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abs-path.d.ts","sourceRoot":"","sources":["../src/abs-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKpD"}
|
package/dist/abs-path.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform absolute path detection.
|
|
3
|
+
*
|
|
4
|
+
* Recognises POSIX absolute paths (`/...`), Windows drive letters (`C:\...`,
|
|
5
|
+
* `D:/...`), and UNC paths (`\\server\share`). Used in path-resolution code
|
|
6
|
+
* that needs to short-circuit when given an already-absolute path without
|
|
7
|
+
* importing the heavier `node:path#isAbsolute`.
|
|
8
|
+
*
|
|
9
|
+
* @task T1883
|
|
10
|
+
*/
|
|
11
|
+
const WINDOWS_DRIVE_RE = /^[A-Za-z]:[\\/]/;
|
|
12
|
+
/**
|
|
13
|
+
* Check if a path is absolute on any supported platform.
|
|
14
|
+
*
|
|
15
|
+
* @param path - Filesystem path to check.
|
|
16
|
+
* @returns `true` for POSIX absolute, Windows drive-rooted, or UNC paths.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* isAbsolutePath('/usr/bin'); // true
|
|
21
|
+
* isAbsolutePath('C:\\Users'); // true
|
|
22
|
+
* isAbsolutePath('\\\\srv\\sh'); // true
|
|
23
|
+
* isAbsolutePath('./relative'); // false
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export function isAbsolutePath(path) {
|
|
29
|
+
if (path.startsWith('/'))
|
|
30
|
+
return true;
|
|
31
|
+
if (WINDOWS_DRIVE_RE.test(path))
|
|
32
|
+
return true;
|
|
33
|
+
if (path.startsWith('\\\\'))
|
|
34
|
+
return true;
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=abs-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abs-path.js","sourceRoot":"","sources":["../src/abs-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAE3C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLEO-bound platform path helpers.
|
|
3
|
+
*
|
|
4
|
+
* Pre-binds {@link createPlatformPathsResolver} to `(appName='cleo', homeEnvVar='CLEO_HOME')`
|
|
5
|
+
* and exposes the cleo-specific helpers every other CLEO package needs:
|
|
6
|
+
* `getCleoHome`, `getCleoPlatformPaths`, `getCleoSystemInfo`, and
|
|
7
|
+
* `getCleoTemplatesTildePath`.
|
|
8
|
+
*
|
|
9
|
+
* @task T1883
|
|
10
|
+
*/
|
|
11
|
+
import { type PlatformPaths, type SystemInfo } from './platform-paths.js';
|
|
12
|
+
/**
|
|
13
|
+
* Get OS-appropriate paths for CLEO's global directories.
|
|
14
|
+
*
|
|
15
|
+
* Linux: `~/.local/share/cleo` | macOS: `~/Library/Application Support/cleo`
|
|
16
|
+
* Windows: `%LOCALAPPDATA%\cleo\Data`
|
|
17
|
+
*
|
|
18
|
+
* The `CLEO_HOME` env var overrides the `data` field. Read fresh on every call.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export declare function getCleoPlatformPaths(): PlatformPaths;
|
|
23
|
+
/**
|
|
24
|
+
* Get the absolute path to CLEO's global data directory.
|
|
25
|
+
*
|
|
26
|
+
* Equivalent to `getCleoPlatformPaths().data` — exposed as a stable named
|
|
27
|
+
* helper because `getCleoHome()` is the most common consumer call.
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export declare function getCleoHome(): string;
|
|
32
|
+
/**
|
|
33
|
+
* Get a cached system information snapshot scoped to CLEO.
|
|
34
|
+
*
|
|
35
|
+
* Includes platform, architecture, hostname, Node version, and resolved
|
|
36
|
+
* CLEO paths. Captured once per process and reused — invalidate via
|
|
37
|
+
* {@link _resetCleoPlatformPathsCache} in tests if needed.
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export declare function getCleoSystemInfo(): SystemInfo;
|
|
42
|
+
/**
|
|
43
|
+
* Get the CLEO templates directory as a tilde-prefixed path for use in
|
|
44
|
+
* `@`-references (AGENTS.md, CLAUDE.md, etc.). Cross-platform: replaces
|
|
45
|
+
* the user's home directory with `~` so the reference resolves consistently
|
|
46
|
+
* when an LLM provider expands `~` at runtime.
|
|
47
|
+
*
|
|
48
|
+
* @returns Tilde-prefixed path like `"~/.local/share/cleo/templates"` on Linux
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const ref = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
|
|
53
|
+
* // "@~/.local/share/cleo/templates/CLEO-INJECTION.md" (Linux)
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
export declare function getCleoTemplatesTildePath(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Invalidate the cached CLEO system info snapshot. Use in tests after
|
|
61
|
+
* mutating `CLEO_HOME` or related env vars.
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
export declare function _resetCleoPlatformPathsCache(): void;
|
|
66
|
+
//# sourceMappingURL=cleo-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleo-paths.d.ts","sourceRoot":"","sources":["../src/cleo-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,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,CAQlD;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLEO-bound platform path helpers.
|
|
3
|
+
*
|
|
4
|
+
* Pre-binds {@link createPlatformPathsResolver} to `(appName='cleo', homeEnvVar='CLEO_HOME')`
|
|
5
|
+
* and exposes the cleo-specific helpers every other CLEO package needs:
|
|
6
|
+
* `getCleoHome`, `getCleoPlatformPaths`, `getCleoSystemInfo`, and
|
|
7
|
+
* `getCleoTemplatesTildePath`.
|
|
8
|
+
*
|
|
9
|
+
* @task T1883
|
|
10
|
+
*/
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { createPlatformPathsResolver, } from './platform-paths.js';
|
|
14
|
+
const TEMPLATES_SUBDIR = 'templates';
|
|
15
|
+
const cleoResolver = createPlatformPathsResolver('cleo', 'CLEO_HOME');
|
|
16
|
+
/**
|
|
17
|
+
* Get OS-appropriate paths for CLEO's global directories.
|
|
18
|
+
*
|
|
19
|
+
* Linux: `~/.local/share/cleo` | macOS: `~/Library/Application Support/cleo`
|
|
20
|
+
* Windows: `%LOCALAPPDATA%\cleo\Data`
|
|
21
|
+
*
|
|
22
|
+
* The `CLEO_HOME` env var overrides the `data` field. Read fresh on every call.
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export function getCleoPlatformPaths() {
|
|
27
|
+
return cleoResolver.getPlatformPaths();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the absolute path to CLEO's global data directory.
|
|
31
|
+
*
|
|
32
|
+
* Equivalent to `getCleoPlatformPaths().data` — exposed as a stable named
|
|
33
|
+
* helper because `getCleoHome()` is the most common consumer call.
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export function getCleoHome() {
|
|
38
|
+
return cleoResolver.getPlatformPaths().data;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get a cached system information snapshot scoped to CLEO.
|
|
42
|
+
*
|
|
43
|
+
* Includes platform, architecture, hostname, Node version, and resolved
|
|
44
|
+
* CLEO paths. Captured once per process and reused — invalidate via
|
|
45
|
+
* {@link _resetCleoPlatformPathsCache} in tests if needed.
|
|
46
|
+
*
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
49
|
+
export function getCleoSystemInfo() {
|
|
50
|
+
return cleoResolver.getSystemInfo();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the CLEO templates directory as a tilde-prefixed path for use in
|
|
54
|
+
* `@`-references (AGENTS.md, CLAUDE.md, etc.). Cross-platform: replaces
|
|
55
|
+
* the user's home directory with `~` so the reference resolves consistently
|
|
56
|
+
* when an LLM provider expands `~` at runtime.
|
|
57
|
+
*
|
|
58
|
+
* @returns Tilde-prefixed path like `"~/.local/share/cleo/templates"` on Linux
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const ref = `@${getCleoTemplatesTildePath()}/CLEO-INJECTION.md`;
|
|
63
|
+
* // "@~/.local/share/cleo/templates/CLEO-INJECTION.md" (Linux)
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export function getCleoTemplatesTildePath() {
|
|
69
|
+
const absPath = join(getCleoHome(), TEMPLATES_SUBDIR);
|
|
70
|
+
const home = homedir();
|
|
71
|
+
if (absPath.startsWith(home)) {
|
|
72
|
+
const relative = absPath.slice(home.length).replace(/\\/g, '/');
|
|
73
|
+
return `~${relative}`;
|
|
74
|
+
}
|
|
75
|
+
return absPath;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Invalidate the cached CLEO system info snapshot. Use in tests after
|
|
79
|
+
* mutating `CLEO_HOME` or related env vars.
|
|
80
|
+
*
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
export function _resetCleoPlatformPathsCache() {
|
|
84
|
+
cleoResolver.resetCache();
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=cleo-paths.js.map
|
|
@@ -0,0 +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;AACjC,OAAO,EACL,2BAA2B,GAG5B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAErC,MAAM,YAAY,GAAG,2BAA2B,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAEtE;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,YAAY,CAAC,gBAAgB,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,YAAY,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,YAAY,CAAC,aAAa,EAAE,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,yBAAyB;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAChE,OAAO,IAAI,QAAQ,EAAE,CAAC;IACxB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B;IAC1C,YAAY,CAAC,UAAU,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@cleocode/paths` — XDG / env-paths SSoT for the CLEO ecosystem.
|
|
3
|
+
*
|
|
4
|
+
* Zero-dep leaf package consumed by `@cleocode/core`, `@cleocode/worktree`,
|
|
5
|
+
* `@cleocode/brain`, `@cleocode/adapters`, and `@cleocode/caamp` to eliminate
|
|
6
|
+
* the env-paths and platform-path duplication that previously existed in
|
|
7
|
+
* each of those packages.
|
|
8
|
+
*
|
|
9
|
+
* Exposes:
|
|
10
|
+
* - {@link createPlatformPathsResolver} — generic factory bindable to any app
|
|
11
|
+
* - CLEO-bound helpers: {@link getCleoHome}, {@link getCleoPlatformPaths},
|
|
12
|
+
* {@link getCleoSystemInfo}, {@link getCleoTemplatesTildePath}
|
|
13
|
+
* - Worktree primitives: {@link computeProjectHash},
|
|
14
|
+
* {@link resolveWorktreeRootForHash}, {@link resolveTaskWorktreePath},
|
|
15
|
+
* {@link getCleoWorktreesRoot}
|
|
16
|
+
* - {@link isAbsolutePath} — cross-platform abs-path check
|
|
17
|
+
*
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
* @task T1883
|
|
20
|
+
*/
|
|
21
|
+
export { isAbsolutePath } from './abs-path.js';
|
|
22
|
+
export { _resetCleoPlatformPathsCache, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, } from './cleo-paths.js';
|
|
23
|
+
export { createPlatformPathsResolver, type PlatformPaths, type PlatformPathsResolver, type SystemInfo, } from './platform-paths.js';
|
|
24
|
+
export { computeProjectHash, getCleoWorktreesRoot, resolveTaskWorktreePath, resolveWorktreeRootForHash, } from './worktree-paths.js';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,4BAA4B,EAC5B,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,GAC1B,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,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@cleocode/paths` — XDG / env-paths SSoT for the CLEO ecosystem.
|
|
3
|
+
*
|
|
4
|
+
* Zero-dep leaf package consumed by `@cleocode/core`, `@cleocode/worktree`,
|
|
5
|
+
* `@cleocode/brain`, `@cleocode/adapters`, and `@cleocode/caamp` to eliminate
|
|
6
|
+
* the env-paths and platform-path duplication that previously existed in
|
|
7
|
+
* each of those packages.
|
|
8
|
+
*
|
|
9
|
+
* Exposes:
|
|
10
|
+
* - {@link createPlatformPathsResolver} — generic factory bindable to any app
|
|
11
|
+
* - CLEO-bound helpers: {@link getCleoHome}, {@link getCleoPlatformPaths},
|
|
12
|
+
* {@link getCleoSystemInfo}, {@link getCleoTemplatesTildePath}
|
|
13
|
+
* - Worktree primitives: {@link computeProjectHash},
|
|
14
|
+
* {@link resolveWorktreeRootForHash}, {@link resolveTaskWorktreePath},
|
|
15
|
+
* {@link getCleoWorktreesRoot}
|
|
16
|
+
* - {@link isAbsolutePath} — cross-platform abs-path check
|
|
17
|
+
*
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
* @task T1883
|
|
20
|
+
*/
|
|
21
|
+
export { isAbsolutePath } from './abs-path.js';
|
|
22
|
+
export { _resetCleoPlatformPathsCache, getCleoHome, getCleoPlatformPaths, getCleoSystemInfo, getCleoTemplatesTildePath, } from './cleo-paths.js';
|
|
23
|
+
export { createPlatformPathsResolver, } from './platform-paths.js';
|
|
24
|
+
export { computeProjectHash, getCleoWorktreesRoot, resolveTaskWorktreePath, resolveWorktreeRootForHash, } from './worktree-paths.js';
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,4BAA4B,EAC5B,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,GAI5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS platform-path resolver factory backed by `env-paths`.
|
|
3
|
+
*
|
|
4
|
+
* The factory is parameterised by `appName` + `homeEnvVar` so a single
|
|
5
|
+
* implementation serves every CLEO package that needs XDG-compliant
|
|
6
|
+
* paths — `cleo`, `agents` (CAAMP), or any future tool — without each
|
|
7
|
+
* package re-implementing the same env-paths wrapper, the same tilde
|
|
8
|
+
* expansion, and the same SystemInfo cache.
|
|
9
|
+
*
|
|
10
|
+
* `getPlatformPaths()` reads fresh on every call: env-paths is microsecond-fast
|
|
11
|
+
* and a process-wide cache would mask XDG / APPDATA env-var changes that test
|
|
12
|
+
* code legitimately makes. `getSystemInfo()` IS cached because hostname /
|
|
13
|
+
* platform / arch don't change during a process lifetime.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
* @task T1883
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* OS-appropriate directory paths for an application.
|
|
20
|
+
*
|
|
21
|
+
* Defaults follow XDG Base Directory on Linux, Apple's File System Programming
|
|
22
|
+
* Guide on macOS, and Microsoft's Known Folders on Windows. The home env-var
|
|
23
|
+
* passed to {@link createPlatformPathsResolver} overrides `data`.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export interface PlatformPaths {
|
|
28
|
+
/** User data dir. Override with the configured home env var. */
|
|
29
|
+
data: string;
|
|
30
|
+
/** OS config dir (XDG_CONFIG_HOME / Library/Preferences / %APPDATA%). */
|
|
31
|
+
config: string;
|
|
32
|
+
/** OS cache dir. */
|
|
33
|
+
cache: string;
|
|
34
|
+
/** OS log dir. */
|
|
35
|
+
log: string;
|
|
36
|
+
/** OS temp dir. */
|
|
37
|
+
temp: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Snapshot of the current system environment combined with resolved platform paths.
|
|
41
|
+
*
|
|
42
|
+
* Cached for the process lifetime by {@link PlatformPathsResolver.getSystemInfo}.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export interface SystemInfo {
|
|
47
|
+
/** Operating system platform identifier. */
|
|
48
|
+
platform: NodeJS.Platform;
|
|
49
|
+
/** CPU architecture (e.g. `"x64"`, `"arm64"`). */
|
|
50
|
+
arch: string;
|
|
51
|
+
/** OS kernel release version string. */
|
|
52
|
+
release: string;
|
|
53
|
+
/** Machine hostname. */
|
|
54
|
+
hostname: string;
|
|
55
|
+
/** Node.js version string (e.g. `"v24.0.0"`). */
|
|
56
|
+
nodeVersion: string;
|
|
57
|
+
/** Resolved platform directory paths. */
|
|
58
|
+
paths: PlatformPaths;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A platform-paths resolver bound to one app name + one home env var.
|
|
62
|
+
*
|
|
63
|
+
* Each resolver carries its own `SystemInfo` cache so resolvers for different
|
|
64
|
+
* apps (e.g. `cleo` vs `agents`) stay fully isolated.
|
|
65
|
+
*
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export interface PlatformPathsResolver {
|
|
69
|
+
/**
|
|
70
|
+
* Get OS-appropriate paths for the resolver's app directories.
|
|
71
|
+
*
|
|
72
|
+
* Reads fresh on every call. The home env var (when set) overrides the
|
|
73
|
+
* `data` field; `~`, `~/...`, absolute, and relative path values are all
|
|
74
|
+
* accepted and resolved against `homedir()`.
|
|
75
|
+
*/
|
|
76
|
+
getPlatformPaths(): PlatformPaths;
|
|
77
|
+
/**
|
|
78
|
+
* Get a cached system information snapshot.
|
|
79
|
+
*
|
|
80
|
+
* Captured once per resolver and reused for the process lifetime. Includes
|
|
81
|
+
* platform, architecture, hostname, Node version, and resolved paths.
|
|
82
|
+
*/
|
|
83
|
+
getSystemInfo(): SystemInfo;
|
|
84
|
+
/**
|
|
85
|
+
* Invalidate the cached system info snapshot. Use in tests after mutating
|
|
86
|
+
* the home env var.
|
|
87
|
+
*
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
resetCache(): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create a platform-paths resolver bound to a specific app name and home env var.
|
|
94
|
+
*
|
|
95
|
+
* Returns a resolver with its own internal `SystemInfo` cache. Path reads are
|
|
96
|
+
* always fresh (env-paths is fast); only system info is cached.
|
|
97
|
+
*
|
|
98
|
+
* @param appName - The application name passed to `env-paths` (e.g. `"cleo"`,
|
|
99
|
+
* `"agents"`).
|
|
100
|
+
* @param homeEnvVar - The env var name that overrides the data directory
|
|
101
|
+
* (e.g. `"CLEO_HOME"`, `"AGENTS_HOME"`). Tilde-prefixed and relative
|
|
102
|
+
* values are resolved against `homedir()`.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const cleo = createPlatformPathsResolver('cleo', 'CLEO_HOME');
|
|
107
|
+
* cleo.getPlatformPaths().data; // → "/home/user/.local/share/cleo" (Linux, no override)
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @public
|
|
111
|
+
*/
|
|
112
|
+
export declare function createPlatformPathsResolver(appName: string, homeEnvVar: string): PlatformPathsResolver;
|
|
113
|
+
//# sourceMappingURL=platform-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-paths.d.ts","sourceRoot":"","sources":["../src/platform-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,KAAK,EAAE,aAAa,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,gBAAgB,IAAI,aAAa,CAAC;IAElC;;;;;OAKG;IACH,aAAa,IAAI,UAAU,CAAC;IAE5B;;;;;OAKG;IACH,UAAU,IAAI,IAAI,CAAC;CACpB;AAqBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,qBAAqB,CAiCvB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS platform-path resolver factory backed by `env-paths`.
|
|
3
|
+
*
|
|
4
|
+
* The factory is parameterised by `appName` + `homeEnvVar` so a single
|
|
5
|
+
* implementation serves every CLEO package that needs XDG-compliant
|
|
6
|
+
* paths — `cleo`, `agents` (CAAMP), or any future tool — without each
|
|
7
|
+
* package re-implementing the same env-paths wrapper, the same tilde
|
|
8
|
+
* expansion, and the same SystemInfo cache.
|
|
9
|
+
*
|
|
10
|
+
* `getPlatformPaths()` reads fresh on every call: env-paths is microsecond-fast
|
|
11
|
+
* and a process-wide cache would mask XDG / APPDATA env-var changes that test
|
|
12
|
+
* code legitimately makes. `getSystemInfo()` IS cached because hostname /
|
|
13
|
+
* platform / arch don't change during a process lifetime.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
* @task T1883
|
|
17
|
+
*/
|
|
18
|
+
import { arch, homedir, hostname, platform, release } from 'node:os';
|
|
19
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
20
|
+
import envPaths from 'env-paths';
|
|
21
|
+
/**
|
|
22
|
+
* Normalize a home-override env var value to an absolute path.
|
|
23
|
+
*
|
|
24
|
+
* Returns `undefined` for absent / blank values so callers fall back to the
|
|
25
|
+
* env-paths default. Accepts `~`, `~/foo`, absolute paths, and relative paths
|
|
26
|
+
* (which are resolved against `homedir()`).
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
function resolveHomeOverride(value) {
|
|
31
|
+
if (value === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
const trimmed = value.trim();
|
|
34
|
+
if (trimmed.length === 0)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (trimmed === '~')
|
|
37
|
+
return homedir();
|
|
38
|
+
if (trimmed.startsWith('~/'))
|
|
39
|
+
return join(homedir(), trimmed.slice(2));
|
|
40
|
+
if (isAbsolute(trimmed))
|
|
41
|
+
return resolve(trimmed);
|
|
42
|
+
return resolve(homedir(), trimmed);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a platform-paths resolver bound to a specific app name and home env var.
|
|
46
|
+
*
|
|
47
|
+
* Returns a resolver with its own internal `SystemInfo` cache. Path reads are
|
|
48
|
+
* always fresh (env-paths is fast); only system info is cached.
|
|
49
|
+
*
|
|
50
|
+
* @param appName - The application name passed to `env-paths` (e.g. `"cleo"`,
|
|
51
|
+
* `"agents"`).
|
|
52
|
+
* @param homeEnvVar - The env var name that overrides the data directory
|
|
53
|
+
* (e.g. `"CLEO_HOME"`, `"AGENTS_HOME"`). Tilde-prefixed and relative
|
|
54
|
+
* values are resolved against `homedir()`.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const cleo = createPlatformPathsResolver('cleo', 'CLEO_HOME');
|
|
59
|
+
* cleo.getPlatformPaths().data; // → "/home/user/.local/share/cleo" (Linux, no override)
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
export function createPlatformPathsResolver(appName, homeEnvVar) {
|
|
65
|
+
let cachedSysInfo = null;
|
|
66
|
+
function readPlatformPaths() {
|
|
67
|
+
const ep = envPaths(appName, { suffix: '' });
|
|
68
|
+
const override = resolveHomeOverride(process.env[homeEnvVar]);
|
|
69
|
+
return {
|
|
70
|
+
data: override ?? ep.data,
|
|
71
|
+
config: ep.config,
|
|
72
|
+
cache: ep.cache,
|
|
73
|
+
log: ep.log,
|
|
74
|
+
temp: ep.temp,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
getPlatformPaths: readPlatformPaths,
|
|
79
|
+
getSystemInfo() {
|
|
80
|
+
if (cachedSysInfo)
|
|
81
|
+
return cachedSysInfo;
|
|
82
|
+
cachedSysInfo = {
|
|
83
|
+
platform: platform(),
|
|
84
|
+
arch: arch(),
|
|
85
|
+
release: release(),
|
|
86
|
+
hostname: hostname(),
|
|
87
|
+
nodeVersion: process.version,
|
|
88
|
+
paths: readPlatformPaths(),
|
|
89
|
+
};
|
|
90
|
+
return cachedSysInfo;
|
|
91
|
+
},
|
|
92
|
+
resetCache() {
|
|
93
|
+
cachedSysInfo = null;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=platform-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-paths.js","sourceRoot":"","sources":["../src/platform-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,QAAQ,MAAM,WAAW,CAAC;AAiFjC;;;;;;;;GAQG;AACH,SAAS,mBAAmB,CAAC,KAAyB;IACpD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,OAAO,EAAE,CAAC;IACtC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,2BAA2B,CACzC,OAAe,EACf,UAAkB;IAElB,IAAI,aAAa,GAAsB,IAAI,CAAC;IAE5C,SAAS,iBAAiB;QACxB,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QAC9D,OAAO;YACL,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,IAAI;YACzB,MAAM,EAAE,EAAE,CAAC,MAAM;YACjB,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,GAAG,EAAE,EAAE,CAAC,GAAG;YACX,IAAI,EAAE,EAAE,CAAC,IAAI;SACd,CAAC;IACJ,CAAC;IAED,OAAO;QACL,gBAAgB,EAAE,iBAAiB;QACnC,aAAa;YACX,IAAI,aAAa;gBAAE,OAAO,aAAa,CAAC;YACxC,aAAa,GAAG;gBACd,QAAQ,EAAE,QAAQ,EAAE;gBACpB,IAAI,EAAE,IAAI,EAAE;gBACZ,OAAO,EAAE,OAAO,EAAE;gBAClB,QAAQ,EAAE,QAAQ,EAAE;gBACpB,WAAW,EAAE,OAAO,CAAC,OAAO;gBAC5B,KAAK,EAAE,iBAAiB,EAAE;aAC3B,CAAC;YACF,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,UAAU;YACR,aAAa,GAAG,IAAI,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worktree path primitives — project hashing + canonical worktree root.
|
|
3
|
+
*
|
|
4
|
+
* Canonical layout per D029:
|
|
5
|
+
* `<cleoHome>/worktrees/<projectHash>/<taskId>/`
|
|
6
|
+
*
|
|
7
|
+
* `cleoHome` is resolved via {@link getCleoHome} (env-paths + `CLEO_HOME` override).
|
|
8
|
+
*
|
|
9
|
+
* @task T1883
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Compute a stable 16-character project hash from an absolute project root path.
|
|
13
|
+
*
|
|
14
|
+
* Uses SHA-256 truncated to 16 hex chars. The truncation is consistent with
|
|
15
|
+
* the historical implementation in `branch-lock.ts#resolveAgentWorktreeRoot`
|
|
16
|
+
* (the root cause of the duplicated logic this package consolidates).
|
|
17
|
+
*
|
|
18
|
+
* @param projectRoot - Absolute path to the project root.
|
|
19
|
+
* @returns 16-character lowercase hex string.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export declare function computeProjectHash(projectRoot: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the worktrees root directory for a given project hash.
|
|
26
|
+
*
|
|
27
|
+
* Result: `<cleoHome>/worktrees/<projectHash>/`
|
|
28
|
+
*
|
|
29
|
+
* Priority:
|
|
30
|
+
* 1. Explicit `worktreeRoot` arg (used by tests / config overrides)
|
|
31
|
+
* 2. `CLEO_HOME` env var via {@link getCleoHome}
|
|
32
|
+
* 3. env-paths XDG data dir via {@link getCleoHome}
|
|
33
|
+
*
|
|
34
|
+
* @param projectHash - 16-char project hash from {@link computeProjectHash}.
|
|
35
|
+
* @param worktreeRoot - Optional explicit override for the full root path.
|
|
36
|
+
* @returns Absolute path to the project-scoped worktree root directory.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveWorktreeRootForHash(projectHash: string, worktreeRoot?: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the worktree directory for a specific task.
|
|
43
|
+
*
|
|
44
|
+
* Result: `<cleoHome>/worktrees/<projectHash>/<taskId>/`
|
|
45
|
+
*
|
|
46
|
+
* @param projectHash - 16-char project hash from {@link computeProjectHash}.
|
|
47
|
+
* @param taskId - The task ID.
|
|
48
|
+
* @param worktreeRoot - Optional override for the worktree root.
|
|
49
|
+
* @returns Absolute path to the task-specific worktree directory.
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveTaskWorktreePath(projectHash: string, taskId: string, worktreeRoot?: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the canonical worktrees-by-project root for the current process —
|
|
56
|
+
* `<cleoHome>/worktrees/`. Project-agnostic; useful when listing or scanning
|
|
57
|
+
* across all projects.
|
|
58
|
+
*
|
|
59
|
+
* @returns Absolute path to `<cleoHome>/worktrees/`.
|
|
60
|
+
*
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
export declare function getCleoWorktreesRoot(): string;
|
|
64
|
+
//# sourceMappingURL=worktree-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-paths.d.ts","sourceRoot":"","sources":["../src/worktree-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D;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,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worktree path primitives — project hashing + canonical worktree root.
|
|
3
|
+
*
|
|
4
|
+
* Canonical layout per D029:
|
|
5
|
+
* `<cleoHome>/worktrees/<projectHash>/<taskId>/`
|
|
6
|
+
*
|
|
7
|
+
* `cleoHome` is resolved via {@link getCleoHome} (env-paths + `CLEO_HOME` override).
|
|
8
|
+
*
|
|
9
|
+
* @task T1883
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from 'node:crypto';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { getCleoHome } from './cleo-paths.js';
|
|
14
|
+
const WORKTREES_SUBDIR = 'worktrees';
|
|
15
|
+
const PROJECT_HASH_LENGTH = 16;
|
|
16
|
+
/**
|
|
17
|
+
* Compute a stable 16-character project hash from an absolute project root path.
|
|
18
|
+
*
|
|
19
|
+
* Uses SHA-256 truncated to 16 hex chars. The truncation is consistent with
|
|
20
|
+
* the historical implementation in `branch-lock.ts#resolveAgentWorktreeRoot`
|
|
21
|
+
* (the root cause of the duplicated logic this package consolidates).
|
|
22
|
+
*
|
|
23
|
+
* @param projectRoot - Absolute path to the project root.
|
|
24
|
+
* @returns 16-character lowercase hex string.
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export function computeProjectHash(projectRoot) {
|
|
29
|
+
return createHash('sha256').update(projectRoot).digest('hex').slice(0, PROJECT_HASH_LENGTH);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the worktrees root directory for a given project hash.
|
|
33
|
+
*
|
|
34
|
+
* Result: `<cleoHome>/worktrees/<projectHash>/`
|
|
35
|
+
*
|
|
36
|
+
* Priority:
|
|
37
|
+
* 1. Explicit `worktreeRoot` arg (used by tests / config overrides)
|
|
38
|
+
* 2. `CLEO_HOME` env var via {@link getCleoHome}
|
|
39
|
+
* 3. env-paths XDG data dir via {@link getCleoHome}
|
|
40
|
+
*
|
|
41
|
+
* @param projectHash - 16-char project hash from {@link computeProjectHash}.
|
|
42
|
+
* @param worktreeRoot - Optional explicit override for the full root path.
|
|
43
|
+
* @returns Absolute path to the project-scoped worktree root directory.
|
|
44
|
+
*
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
export function resolveWorktreeRootForHash(projectHash, worktreeRoot) {
|
|
48
|
+
if (worktreeRoot)
|
|
49
|
+
return worktreeRoot;
|
|
50
|
+
return join(getCleoHome(), WORKTREES_SUBDIR, projectHash);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the worktree directory for a specific task.
|
|
54
|
+
*
|
|
55
|
+
* Result: `<cleoHome>/worktrees/<projectHash>/<taskId>/`
|
|
56
|
+
*
|
|
57
|
+
* @param projectHash - 16-char project hash from {@link computeProjectHash}.
|
|
58
|
+
* @param taskId - The task ID.
|
|
59
|
+
* @param worktreeRoot - Optional override for the worktree root.
|
|
60
|
+
* @returns Absolute path to the task-specific worktree directory.
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
export function resolveTaskWorktreePath(projectHash, taskId, worktreeRoot) {
|
|
65
|
+
return join(resolveWorktreeRootForHash(projectHash, worktreeRoot), taskId);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Resolve the canonical worktrees-by-project root for the current process —
|
|
69
|
+
* `<cleoHome>/worktrees/`. Project-agnostic; useful when listing or scanning
|
|
70
|
+
* across all projects.
|
|
71
|
+
*
|
|
72
|
+
* @returns Absolute path to `<cleoHome>/worktrees/`.
|
|
73
|
+
*
|
|
74
|
+
* @public
|
|
75
|
+
*/
|
|
76
|
+
export function getCleoWorktreesRoot() {
|
|
77
|
+
return join(getCleoHome(), WORKTREES_SUBDIR);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=worktree-paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-paths.js","sourceRoot":"","sources":["../src/worktree-paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;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;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;AAC9F,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAAmB,EAAE,YAAqB;IACnF,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IACtC,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CACrC,WAAmB,EACnB,MAAc,EACd,YAAqB;IAErB,OAAO,IAAI,CAAC,0BAA0B,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAC/C,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cleocode/paths",
|
|
3
|
+
"version": "2026.5.26",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
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.",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"cleo",
|
|
21
|
+
"paths",
|
|
22
|
+
"xdg",
|
|
23
|
+
"env-paths",
|
|
24
|
+
"platform"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=24.0.0"
|
|
28
|
+
},
|
|
29
|
+
"author": "CLEO Code <hello@cleocode.dev>",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"env-paths": "^4.0.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^24.3.0",
|
|
36
|
+
"typescript": "^6.0.2",
|
|
37
|
+
"vitest": "^4.1.4"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/kryptobaseddev/cleo.git",
|
|
45
|
+
"directory": "packages/paths"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -b",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest"
|
|
51
|
+
}
|
|
52
|
+
}
|