ppcos 1.0.4 → 1.0.6
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/lib/commands/update.js +23 -0
- package/lib/utils/fs-helpers.js +17 -6
- package/package.json +1 -1
package/lib/commands/update.js
CHANGED
|
@@ -218,6 +218,28 @@ function migrateConfigManagedTypes(manifest) {
|
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* One-time migration: remove leaked data files from skill tmp/ directories.
|
|
223
|
+
* Data files were accidentally included in .claude-base.zip and distributed
|
|
224
|
+
* to clients. This removes them and cleans up the manifest.
|
|
225
|
+
*/
|
|
226
|
+
function migrateTmpDataFiles(clientDir, manifest) {
|
|
227
|
+
const keepFiles = new Set(['.gitkeep', '.gitignore']);
|
|
228
|
+
let removed = 0;
|
|
229
|
+
for (const [path] of Object.entries(manifest.managedFiles)) {
|
|
230
|
+
if (!/\/tmp\//.test(path)) continue;
|
|
231
|
+
const filename = path.split('/').pop();
|
|
232
|
+
if (keepFiles.has(filename)) continue;
|
|
233
|
+
const fullPath = join(clientDir, path);
|
|
234
|
+
if (existsSync(fullPath)) unlinkSync(fullPath);
|
|
235
|
+
delete manifest.managedFiles[path];
|
|
236
|
+
removed++;
|
|
237
|
+
}
|
|
238
|
+
if (removed > 0) {
|
|
239
|
+
logger.info(` Removed ${removed} tmp data file${removed !== 1 ? 's' : ''} from tmp/`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
221
243
|
/**
|
|
222
244
|
* Find all client directories with .managed.json
|
|
223
245
|
* @returns {string[]} Array of client names
|
|
@@ -383,6 +405,7 @@ async function updateClient(clientName, basePathOrOptions = {}, options = {}) {
|
|
|
383
405
|
migrateSettingsHooks(clientDir);
|
|
384
406
|
migrateManifestKeys(manifest);
|
|
385
407
|
migrateConfigManagedTypes(manifest);
|
|
408
|
+
migrateTmpDataFiles(clientDir, manifest);
|
|
386
409
|
|
|
387
410
|
// Check if already up to date
|
|
388
411
|
if (currentVersion === packageVersion) {
|
package/lib/utils/fs-helpers.js
CHANGED
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
* File system helper utilities
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { readdir, stat, mkdir, copyFile, access } from 'node:fs/promises';
|
|
6
|
-
import { readdirSync, statSync, mkdirSync, copyFileSync, existsSync } from 'node:fs';
|
|
5
|
+
import { readdir, stat, mkdir, copyFile, access, chmod } from 'node:fs/promises';
|
|
6
|
+
import { readdirSync, statSync, mkdirSync, copyFileSync, existsSync, chmodSync } from 'node:fs';
|
|
7
7
|
import { join, relative, dirname } from 'node:path';
|
|
8
8
|
import { constants } from 'node:fs';
|
|
9
9
|
|
|
10
|
+
// Directories to skip during template file enumeration.
|
|
11
|
+
// tmp/ dirs hold generated runtime data (analysis output, caches)
|
|
12
|
+
// that must never be distributed to clients.
|
|
13
|
+
const EXCLUDED_DIR_NAMES = new Set(['tmp']);
|
|
14
|
+
|
|
10
15
|
/**
|
|
11
16
|
* Check if a file exists (async)
|
|
12
17
|
* @param {string} filePath - Path to check
|
|
@@ -36,14 +41,15 @@ export function fileExistsSync(filePath) {
|
|
|
36
41
|
* @param {string} [baseDir] - Base directory for relative paths
|
|
37
42
|
* @returns {Promise<string[]>} Array of relative file paths
|
|
38
43
|
*/
|
|
39
|
-
export async function getAllFiles(dir, baseDir = dir) {
|
|
44
|
+
export async function getAllFiles(dir, baseDir = dir, excludeDirs = EXCLUDED_DIR_NAMES) {
|
|
40
45
|
const files = [];
|
|
41
46
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
42
47
|
|
|
43
48
|
for (const entry of entries) {
|
|
44
49
|
const fullPath = join(dir, entry.name);
|
|
45
50
|
if (entry.isDirectory()) {
|
|
46
|
-
|
|
51
|
+
if (excludeDirs.has(entry.name)) continue;
|
|
52
|
+
files.push(...await getAllFiles(fullPath, baseDir, excludeDirs));
|
|
47
53
|
} else {
|
|
48
54
|
files.push(relative(baseDir, fullPath).replace(/\\/g, '/'));
|
|
49
55
|
}
|
|
@@ -58,14 +64,15 @@ export async function getAllFiles(dir, baseDir = dir) {
|
|
|
58
64
|
* @param {string} [baseDir] - Base directory for relative paths
|
|
59
65
|
* @returns {string[]} Array of relative file paths
|
|
60
66
|
*/
|
|
61
|
-
export function getAllFilesSync(dir, baseDir = dir) {
|
|
67
|
+
export function getAllFilesSync(dir, baseDir = dir, excludeDirs = EXCLUDED_DIR_NAMES) {
|
|
62
68
|
const files = [];
|
|
63
69
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
64
70
|
|
|
65
71
|
for (const entry of entries) {
|
|
66
72
|
const fullPath = join(dir, entry.name);
|
|
67
73
|
if (entry.isDirectory()) {
|
|
68
|
-
|
|
74
|
+
if (excludeDirs.has(entry.name)) continue;
|
|
75
|
+
files.push(...getAllFilesSync(fullPath, baseDir, excludeDirs));
|
|
69
76
|
} else {
|
|
70
77
|
files.push(relative(baseDir, fullPath).replace(/\\/g, '/'));
|
|
71
78
|
}
|
|
@@ -83,6 +90,8 @@ export async function copyFileWithDirs(src, dest) {
|
|
|
83
90
|
const destDir = dirname(dest);
|
|
84
91
|
await mkdir(destDir, { recursive: true });
|
|
85
92
|
await copyFile(src, dest);
|
|
93
|
+
const srcStats = await stat(src);
|
|
94
|
+
await chmod(dest, srcStats.mode);
|
|
86
95
|
}
|
|
87
96
|
|
|
88
97
|
/**
|
|
@@ -96,6 +105,8 @@ export function copyFileWithDirsSync(src, dest) {
|
|
|
96
105
|
mkdirSync(destDir, { recursive: true });
|
|
97
106
|
}
|
|
98
107
|
copyFileSync(src, dest);
|
|
108
|
+
const srcStats = statSync(src);
|
|
109
|
+
chmodSync(dest, srcStats.mode);
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
/**
|