rhachet 1.19.14 → 1.19.15
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.
|
@@ -7,14 +7,15 @@ const node_path_1 = require("node:path");
|
|
|
7
7
|
* .what = recursively counts all leaf files in a directory
|
|
8
8
|
* .why = to provide accurate file counts when linking directories
|
|
9
9
|
*/
|
|
10
|
-
const countFilesInDirectory = (
|
|
10
|
+
const countFilesInDirectory = (input) => {
|
|
11
|
+
const { dirPath } = input;
|
|
11
12
|
let count = 0;
|
|
12
13
|
const entries = (0, node_fs_1.readdirSync)(dirPath);
|
|
13
14
|
for (const entry of entries) {
|
|
14
15
|
const fullPath = (0, node_path_1.resolve)(dirPath, entry);
|
|
15
16
|
const stats = (0, node_fs_1.statSync)(fullPath);
|
|
16
17
|
if (stats.isDirectory()) {
|
|
17
|
-
count += countFilesInDirectory(fullPath);
|
|
18
|
+
count += countFilesInDirectory({ dirPath: fullPath });
|
|
18
19
|
}
|
|
19
20
|
else if (stats.isFile()) {
|
|
20
21
|
count++;
|
|
@@ -26,7 +27,8 @@ const countFilesInDirectory = (dirPath) => {
|
|
|
26
27
|
* .what = recursively sets all files and directories to readonly and executable
|
|
27
28
|
* .why = prevents agents from accidentally or maliciously overwriting linked resources from node_modules, while allowing skills to be executed
|
|
28
29
|
*/
|
|
29
|
-
const setDirectoryReadonlyExecutable = (
|
|
30
|
+
const setDirectoryReadonlyExecutable = (input) => {
|
|
31
|
+
const { dirPath } = input;
|
|
30
32
|
const entries = (0, node_fs_1.readdirSync)(dirPath);
|
|
31
33
|
for (const entry of entries) {
|
|
32
34
|
const fullPath = (0, node_path_1.resolve)(dirPath, entry);
|
|
@@ -36,7 +38,7 @@ const setDirectoryReadonlyExecutable = (dirPath) => {
|
|
|
36
38
|
continue;
|
|
37
39
|
if (lstats.isDirectory()) {
|
|
38
40
|
// recurse first, then set directory permissions
|
|
39
|
-
setDirectoryReadonlyExecutable(fullPath);
|
|
41
|
+
setDirectoryReadonlyExecutable({ dirPath: fullPath });
|
|
40
42
|
// r-x for directories (need execute to traverse)
|
|
41
43
|
(0, node_fs_1.chmodSync)(fullPath, 0o555);
|
|
42
44
|
}
|
|
@@ -48,6 +50,53 @@ const setDirectoryReadonlyExecutable = (dirPath) => {
|
|
|
48
50
|
// set the root directory itself to readonly after processing contents
|
|
49
51
|
(0, node_fs_1.chmodSync)(dirPath, 0o555);
|
|
50
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* .what = remove path if it exists (symlink, file, or directory)
|
|
55
|
+
* .why = upsert semantics - always succeed even if target already exists, including broken symlinks
|
|
56
|
+
*/
|
|
57
|
+
const clearPath = (input) => {
|
|
58
|
+
const { targetPath } = input;
|
|
59
|
+
const lstats = (() => {
|
|
60
|
+
try {
|
|
61
|
+
return (0, node_fs_1.lstatSync)(targetPath);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error.code === 'ENOENT')
|
|
65
|
+
return null;
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
})();
|
|
69
|
+
if (!lstats)
|
|
70
|
+
return 'created';
|
|
71
|
+
try {
|
|
72
|
+
(0, node_fs_1.unlinkSync)(targetPath);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
(0, node_fs_1.rmSync)(targetPath, { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
return 'updated';
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* .what = create a symlink from targetPath to sourcePath, clear existing, log action
|
|
81
|
+
* .why = shared logic for both single-dir and array-dir modes
|
|
82
|
+
*/
|
|
83
|
+
const linkSourceToTarget = (input) => {
|
|
84
|
+
const { sourcePath, targetPath } = input;
|
|
85
|
+
// clear existing and log
|
|
86
|
+
const relativeTargetPath = (0, node_path_1.relative)(process.cwd(), targetPath);
|
|
87
|
+
const action = clearPath({ targetPath });
|
|
88
|
+
console.log(action === 'updated'
|
|
89
|
+
? ` ↻ ${relativeTargetPath} (updated)`
|
|
90
|
+
: ` + ${relativeTargetPath}`);
|
|
91
|
+
// create parent directory if needed
|
|
92
|
+
const targetParent = (0, node_path_1.resolve)(targetPath, '..');
|
|
93
|
+
(0, node_fs_1.mkdirSync)(targetParent, { recursive: true });
|
|
94
|
+
// create relative symlink
|
|
95
|
+
const relativeSource = (0, node_path_1.relative)(targetParent, sourcePath);
|
|
96
|
+
(0, node_fs_1.symlinkSync)(relativeSource, targetPath, 'dir');
|
|
97
|
+
setDirectoryReadonlyExecutable({ dirPath: sourcePath });
|
|
98
|
+
return countFilesInDirectory({ dirPath: sourcePath });
|
|
99
|
+
};
|
|
51
100
|
/**
|
|
52
101
|
* .what = creates symlinks for resource directories to a target directory
|
|
53
102
|
* .why = enables role resources (briefs, skills, etc.) to be linked from node_modules or other sources
|
|
@@ -57,88 +106,34 @@ const setDirectoryReadonlyExecutable = (dirPath) => {
|
|
|
57
106
|
* - returns count of leaf files
|
|
58
107
|
*/
|
|
59
108
|
const symlinkResourceDirectories = (options) => {
|
|
60
|
-
const { sourceDirs, targetDir
|
|
61
|
-
//
|
|
109
|
+
const { sourceDirs, targetDir } = options;
|
|
110
|
+
// single-dir mode: symlink source dir directly as target dir
|
|
62
111
|
if (!Array.isArray(sourceDirs)) {
|
|
63
112
|
const sourcePath = (0, node_path_1.resolve)(process.cwd(), sourceDirs.uri);
|
|
64
113
|
if (!(0, node_fs_1.existsSync)(sourcePath))
|
|
65
114
|
return 0;
|
|
66
|
-
|
|
67
|
-
const relativeTargetPath = (0, node_path_1.relative)(process.cwd(), targetDir);
|
|
68
|
-
if ((0, node_fs_1.existsSync)(targetDir)) {
|
|
69
|
-
try {
|
|
70
|
-
(0, node_fs_1.unlinkSync)(targetDir);
|
|
71
|
-
console.log(` ↻ ${relativeTargetPath} (updated)`);
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
(0, node_fs_1.rmSync)(targetDir, { recursive: true, force: true });
|
|
75
|
-
console.log(` ↻ ${relativeTargetPath} (updated)`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
console.log(` + ${relativeTargetPath}`);
|
|
80
|
-
}
|
|
81
|
-
// create parent directory if needed
|
|
82
|
-
const targetParent = (0, node_path_1.resolve)(targetDir, '..');
|
|
83
|
-
(0, node_fs_1.mkdirSync)(targetParent, { recursive: true });
|
|
84
|
-
// create relative symlink: targetDir -> sourcePath
|
|
85
|
-
const relativeSource = (0, node_path_1.relative)(targetParent, sourcePath);
|
|
86
|
-
(0, node_fs_1.symlinkSync)(relativeSource, targetDir, 'dir');
|
|
87
|
-
setDirectoryReadonlyExecutable(sourcePath);
|
|
88
|
-
return countFilesInDirectory(sourcePath);
|
|
115
|
+
return linkSourceToTarget({ sourcePath, targetPath: targetDir });
|
|
89
116
|
}
|
|
90
|
-
//
|
|
91
|
-
// calculate expected symlink names based on source directories
|
|
92
|
-
const expectedNames = new Set(sourceDirs.map((dir) => (0, node_path_1.basename)(dir.uri)));
|
|
117
|
+
// array-dir mode: symlink each source dir within target dir
|
|
93
118
|
// remove deprecated symlinks (ones that exist but are no longer in the config)
|
|
119
|
+
const expectedNames = new Set(sourceDirs.map((dir) => (0, node_path_1.basename)(dir.uri)));
|
|
94
120
|
if ((0, node_fs_1.existsSync)(targetDir)) {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
(0, node_fs_1.unlinkSync)(entryPath);
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
(0, node_fs_1.rmSync)(entryPath, { recursive: true, force: true });
|
|
105
|
-
}
|
|
106
|
-
console.log(` - ${relativeEntryPath} (removed, no longer in role)`);
|
|
107
|
-
}
|
|
121
|
+
for (const entry of (0, node_fs_1.readdirSync)(targetDir)) {
|
|
122
|
+
if (expectedNames.has(entry))
|
|
123
|
+
continue;
|
|
124
|
+
const entryPath = (0, node_path_1.resolve)(targetDir, entry);
|
|
125
|
+
clearPath({ targetPath: entryPath });
|
|
126
|
+
console.log(` - ${(0, node_path_1.relative)(process.cwd(), entryPath)} (removed, no longer in role)`);
|
|
108
127
|
}
|
|
109
128
|
}
|
|
110
|
-
|
|
111
|
-
return 0;
|
|
129
|
+
// create symlinks for each source dir
|
|
112
130
|
let totalFileCount = 0;
|
|
113
131
|
for (const sourceDir of sourceDirs) {
|
|
114
132
|
const sourcePath = (0, node_path_1.resolve)(process.cwd(), sourceDir.uri);
|
|
115
133
|
if (!(0, node_fs_1.existsSync)(sourcePath))
|
|
116
134
|
continue;
|
|
117
|
-
// create target directory parent if needed
|
|
118
|
-
(0, node_fs_1.mkdirSync)(targetDir, { recursive: true });
|
|
119
|
-
// create a unique target path for this source directory
|
|
120
135
|
const targetPath = (0, node_path_1.resolve)(targetDir, (0, node_path_1.basename)(sourcePath));
|
|
121
|
-
|
|
122
|
-
const relativeTargetPath = (0, node_path_1.relative)(process.cwd(), targetPath);
|
|
123
|
-
if ((0, node_fs_1.existsSync)(targetPath)) {
|
|
124
|
-
try {
|
|
125
|
-
(0, node_fs_1.unlinkSync)(targetPath);
|
|
126
|
-
console.log(` ↻ ${relativeTargetPath} (updated)`);
|
|
127
|
-
}
|
|
128
|
-
catch {
|
|
129
|
-
(0, node_fs_1.rmSync)(targetPath, { recursive: true, force: true });
|
|
130
|
-
console.log(` ↻ ${relativeTargetPath} (updated)`);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
console.log(` + ${relativeTargetPath}`);
|
|
135
|
-
}
|
|
136
|
-
// create relative symlink from target directory to source directory
|
|
137
|
-
const relativeSource = (0, node_path_1.relative)(targetDir, sourcePath);
|
|
138
|
-
(0, node_fs_1.symlinkSync)(relativeSource, targetPath, 'dir');
|
|
139
|
-
setDirectoryReadonlyExecutable(sourcePath);
|
|
140
|
-
const fileCount = countFilesInDirectory(sourcePath);
|
|
141
|
-
totalFileCount += fileCount;
|
|
136
|
+
totalFileCount += linkSourceToTarget({ sourcePath, targetPath });
|
|
142
137
|
}
|
|
143
138
|
return totalFileCount;
|
|
144
139
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symlinkResourceDirectories.js","sourceRoot":"","sources":["../../../../src/domain.operations/invoke/link/symlinkResourceDirectories.ts"],"names":[],"mappings":";;;AAAA,qCAUiB;AACjB,yCAAwD;AAExD;;;GAGG;AACH,MAAM,qBAAqB,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"symlinkResourceDirectories.js","sourceRoot":"","sources":["../../../../src/domain.operations/invoke/link/symlinkResourceDirectories.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "rhachet",
|
|
3
3
|
"author": "ehmpathy",
|
|
4
4
|
"description": "A framework for reliable, thorough thought. Weave threads of thought via stitches.",
|
|
5
|
-
"version": "1.19.
|
|
5
|
+
"version": "1.19.15",
|
|
6
6
|
"repository": "ehmpathy/rhachet",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet",
|
|
8
8
|
"keywords": [
|