@slats/claude-assets-sync 0.0.4 → 0.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/dist/commands/add.cjs +2 -7
- package/dist/commands/add.mjs +2 -7
- package/dist/commands/index.d.ts +22 -0
- package/dist/commands/remove.cjs +6 -6
- package/dist/commands/remove.mjs +6 -6
- package/dist/commands/types.d.ts +2 -4
- package/dist/commands/update.cjs +178 -0
- package/dist/commands/update.d.ts +13 -0
- package/dist/commands/update.mjs +176 -0
- package/dist/components/add/AddCommand.cjs +11 -0
- package/dist/components/add/AddCommand.mjs +11 -0
- package/dist/components/list/ListCommand.cjs +65 -47
- package/dist/components/list/ListCommand.mjs +66 -48
- package/dist/components/status/StatusDisplay.cjs +4 -3
- package/dist/components/status/StatusDisplay.d.ts +2 -4
- package/dist/components/status/StatusDisplay.mjs +4 -3
- package/dist/components/tree/AssetTreeNode.cjs +21 -4
- package/dist/components/tree/AssetTreeNode.d.ts +1 -1
- package/dist/components/tree/AssetTreeNode.mjs +21 -4
- package/dist/components/tree/TreeSelect.cjs +14 -6
- package/dist/components/tree/TreeSelect.mjs +14 -6
- package/dist/core/cli.cjs +18 -0
- package/dist/core/cli.mjs +18 -0
- package/dist/core/constants.cjs +4 -1
- package/dist/core/constants.d.ts +8 -1
- package/dist/core/constants.mjs +4 -1
- package/dist/core/filesystem.cjs +7 -13
- package/dist/core/filesystem.mjs +7 -13
- package/dist/core/localSource.cjs +112 -0
- package/dist/core/localSource.d.ts +33 -0
- package/dist/core/localSource.mjs +106 -0
- package/dist/core/migration.cjs +10 -9
- package/dist/core/migration.mjs +10 -9
- package/dist/core/packageScanner.cjs +94 -1
- package/dist/core/packageScanner.d.ts +6 -1
- package/dist/core/packageScanner.mjs +94 -2
- package/dist/core/sync.cjs +118 -46
- package/dist/core/sync.mjs +119 -47
- package/dist/core/syncMeta.cjs +153 -9
- package/dist/core/syncMeta.d.ts +22 -18
- package/dist/core/syncMeta.mjs +149 -9
- package/dist/utils/types.d.ts +24 -7
- package/dist/version.cjs +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +1 -1
package/dist/core/sync.mjs
CHANGED
|
@@ -1,13 +1,47 @@
|
|
|
1
1
|
import { logger } from '../utils/logger.mjs';
|
|
2
2
|
import { toFlatFileName } from '../utils/nameTransform.mjs';
|
|
3
|
-
import { findGitRoot, readLocalPackageJson, readPackageJson, parseGitHubRepo,
|
|
3
|
+
import { findGitRoot, readLocalPackageJson, readPackageJson, parseGitHubRepo, buildAssetPath, getAssetTypes, buildVersionTag } from '../utils/package.mjs';
|
|
4
4
|
import { packageNameToPrefix } from '../utils/packageName.mjs';
|
|
5
5
|
import { getDestinationDir, getFlatDestinationDir } from '../utils/paths.mjs';
|
|
6
6
|
import { cleanAssetDir, cleanFlatAssetFiles, writeAssetFile, writeFlatAssetFile, needsSync, writeSyncMeta, createSyncMeta } from './filesystem.mjs';
|
|
7
7
|
import { fetchAssetFiles, downloadAssetFiles, RateLimitError } from './github.mjs';
|
|
8
|
+
import { canUseLocalSource, fetchLocalAssetFiles, downloadLocalAssetFiles } from './localSource.mjs';
|
|
8
9
|
import { readUnifiedSyncMeta, createEmptyUnifiedMeta, needsSyncUnified, updatePackageInMeta, writeUnifiedSyncMeta } from './syncMeta.mjs';
|
|
10
|
+
import { SCHEMA_VERSIONS } from './constants.mjs';
|
|
9
11
|
import { getAssetStructure } from './assetStructure.mjs';
|
|
10
12
|
|
|
13
|
+
function groupEntriesIntoSkillUnits(entries, prefix) {
|
|
14
|
+
const dirGroups = new Map();
|
|
15
|
+
const singleFiles = [];
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const slashIndex = entry.name.indexOf('/');
|
|
18
|
+
if (slashIndex === -1) {
|
|
19
|
+
singleFiles.push({
|
|
20
|
+
name: entry.name,
|
|
21
|
+
isDirectory: false,
|
|
22
|
+
transformed: toFlatFileName(prefix, entry.name),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const dirName = entry.name.substring(0, slashIndex);
|
|
27
|
+
const internalFile = entry.name.substring(slashIndex + 1);
|
|
28
|
+
if (!dirGroups.has(dirName)) {
|
|
29
|
+
dirGroups.set(dirName, []);
|
|
30
|
+
}
|
|
31
|
+
dirGroups.get(dirName).push(internalFile);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const dirSkillUnits = [];
|
|
35
|
+
for (const [dirName, internalFiles] of dirGroups.entries()) {
|
|
36
|
+
dirSkillUnits.push({
|
|
37
|
+
name: dirName,
|
|
38
|
+
isDirectory: true,
|
|
39
|
+
transformed: toFlatFileName(prefix, dirName),
|
|
40
|
+
internalFiles,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return [...singleFiles, ...dirSkillUnits];
|
|
44
|
+
}
|
|
11
45
|
const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions, outputDir) => {
|
|
12
46
|
logger.packageStart(packageName);
|
|
13
47
|
try {
|
|
@@ -32,14 +66,6 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
32
66
|
reason: 'Package does not have claude.assetPath in package.json',
|
|
33
67
|
};
|
|
34
68
|
const repoInfo = parseGitHubRepo(packageInfo.repository);
|
|
35
|
-
if (!repoInfo) {
|
|
36
|
-
return {
|
|
37
|
-
packageName,
|
|
38
|
-
success: false,
|
|
39
|
-
skipped: true,
|
|
40
|
-
reason: 'Unable to parse GitHub repository URL',
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
69
|
const useFlat = options.flat !== false;
|
|
44
70
|
if (useFlat) {
|
|
45
71
|
const prefix = packageNameToPrefix(packageName);
|
|
@@ -53,11 +79,32 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
53
79
|
reason: `Already synced at version ${packageInfo.version}`,
|
|
54
80
|
};
|
|
55
81
|
}
|
|
56
|
-
const tag = options.ref ?? buildVersionTag(packageName, packageInfo.version);
|
|
57
82
|
const assetPath = buildAssetPath(packageInfo.claude.assetPath);
|
|
58
|
-
|
|
83
|
+
const useLocalSource = options.ref
|
|
84
|
+
? { available: false }
|
|
85
|
+
: canUseLocalSource(packageName, packageInfo.version, assetPath, cwd);
|
|
59
86
|
const assetTypes = getAssetTypes(packageInfo.claude);
|
|
60
|
-
|
|
87
|
+
let assetFiles;
|
|
88
|
+
let isLocalSource;
|
|
89
|
+
if (useLocalSource.available && useLocalSource.docsPath) {
|
|
90
|
+
isLocalSource = true;
|
|
91
|
+
logger.step('Using', 'local docs from node_modules');
|
|
92
|
+
assetFiles = await fetchLocalAssetFiles(useLocalSource.docsPath, assetTypes);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
if (!repoInfo) {
|
|
96
|
+
return {
|
|
97
|
+
packageName,
|
|
98
|
+
success: false,
|
|
99
|
+
skipped: true,
|
|
100
|
+
reason: `Package ${packageName} has no valid GitHub repository URL for remote fetch`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
isLocalSource = false;
|
|
104
|
+
const tag = options.ref ?? buildVersionTag(packageName, packageInfo.version);
|
|
105
|
+
logger.step('Fetching', `asset list from GitHub (ref: ${tag})`);
|
|
106
|
+
assetFiles = await fetchAssetFiles(repoInfo, assetPath, tag, assetTypes);
|
|
107
|
+
}
|
|
61
108
|
let totalFiles = 0;
|
|
62
109
|
for (const assetType of assetTypes) {
|
|
63
110
|
totalFiles += (assetFiles[assetType] || []).length;
|
|
@@ -88,45 +135,41 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
88
135
|
continue;
|
|
89
136
|
const structure = getAssetStructure(assetType, packageInfo.claude);
|
|
90
137
|
if (structure === 'nested') {
|
|
91
|
-
fileMappings[assetType] = filteredEntries.map((e) =>
|
|
138
|
+
fileMappings[assetType] = filteredEntries.map((e) => ({
|
|
139
|
+
name: e.name,
|
|
140
|
+
isDirectory: false,
|
|
141
|
+
}));
|
|
92
142
|
}
|
|
93
143
|
else {
|
|
94
|
-
fileMappings[assetType] = filteredEntries
|
|
95
|
-
original: entry.name,
|
|
96
|
-
transformed: toFlatFileName(prefix, entry.name),
|
|
97
|
-
}));
|
|
144
|
+
fileMappings[assetType] = groupEntriesIntoSkillUnits(filteredEntries, prefix);
|
|
98
145
|
}
|
|
99
146
|
}
|
|
100
147
|
if (options.dryRun) {
|
|
101
148
|
for (const assetType of assetTypes) {
|
|
102
|
-
const
|
|
103
|
-
if (!
|
|
149
|
+
const units = fileMappings[assetType];
|
|
150
|
+
if (!units || units.length === 0)
|
|
104
151
|
continue;
|
|
105
152
|
const structure = getAssetStructure(assetType, packageInfo.claude);
|
|
106
153
|
if (structure === 'nested') {
|
|
107
154
|
logger.step(`Would sync ${assetType} to`, getDestinationDir(destDir, packageName, assetType));
|
|
108
|
-
|
|
109
|
-
logger.file('create',
|
|
155
|
+
units.forEach((unit) => {
|
|
156
|
+
logger.file('create', unit.name);
|
|
110
157
|
});
|
|
111
158
|
}
|
|
112
159
|
else {
|
|
113
160
|
logger.step(`Would sync ${assetType} to`, getFlatDestinationDir(destDir, assetType));
|
|
114
|
-
|
|
115
|
-
|
|
161
|
+
units.forEach((unit) => {
|
|
162
|
+
const displayName = unit.transformed ?? unit.name;
|
|
163
|
+
logger.file('create', displayName);
|
|
116
164
|
});
|
|
117
165
|
}
|
|
118
166
|
}
|
|
119
167
|
const syncedFiles = {};
|
|
120
168
|
for (const assetType of assetTypes) {
|
|
121
|
-
const
|
|
122
|
-
if (!
|
|
169
|
+
const units = fileMappings[assetType];
|
|
170
|
+
if (!units || units.length === 0)
|
|
123
171
|
continue;
|
|
124
|
-
|
|
125
|
-
syncedFiles[assetType] = mappings;
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
syncedFiles[assetType] = mappings.map((m) => m.transformed);
|
|
129
|
-
}
|
|
172
|
+
syncedFiles[assetType] = units.map((u) => u.transformed ?? u.name);
|
|
130
173
|
}
|
|
131
174
|
return {
|
|
132
175
|
packageName,
|
|
@@ -158,7 +201,14 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
158
201
|
continue;
|
|
159
202
|
const structure = getAssetStructure(assetType, packageInfo.claude);
|
|
160
203
|
logger.step('Downloading', assetType);
|
|
161
|
-
|
|
204
|
+
let downloadedFiles;
|
|
205
|
+
if (isLocalSource && useLocalSource.docsPath) {
|
|
206
|
+
downloadedFiles = await downloadLocalAssetFiles(useLocalSource.docsPath, assetType, filteredEntries);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const tag = options.ref ?? buildVersionTag(packageName, packageInfo.version);
|
|
210
|
+
downloadedFiles = await downloadAssetFiles(repoInfo, assetPath, assetType, filteredEntries, tag);
|
|
211
|
+
}
|
|
162
212
|
if (structure === 'nested') {
|
|
163
213
|
for (const [fileName, content] of downloadedFiles) {
|
|
164
214
|
writeAssetFile(destDir, packageName, assetType, fileName, content);
|
|
@@ -166,10 +216,8 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
166
216
|
}
|
|
167
217
|
}
|
|
168
218
|
else {
|
|
169
|
-
const mappings = fileMappings[assetType];
|
|
170
219
|
for (const [fileName, content] of downloadedFiles) {
|
|
171
|
-
const
|
|
172
|
-
const flatName = mapping?.transformed ?? toFlatFileName(prefix, fileName);
|
|
220
|
+
const flatName = toFlatFileName(prefix, fileName);
|
|
173
221
|
writeFlatAssetFile(destDir, assetType, flatName, content);
|
|
174
222
|
logger.file('create', flatName);
|
|
175
223
|
}
|
|
@@ -185,18 +233,14 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
185
233
|
? exclusions
|
|
186
234
|
: undefined,
|
|
187
235
|
});
|
|
236
|
+
updatedMeta.skillUnitFormat = SCHEMA_VERSIONS.SKILL_UNIT_FORMAT;
|
|
188
237
|
writeUnifiedSyncMeta(destDir, updatedMeta);
|
|
189
238
|
const syncedFiles = {};
|
|
190
239
|
for (const assetType of assetTypes) {
|
|
191
|
-
const
|
|
192
|
-
if (!
|
|
240
|
+
const units = fileMappings[assetType];
|
|
241
|
+
if (!units || units.length === 0)
|
|
193
242
|
continue;
|
|
194
|
-
|
|
195
|
-
syncedFiles[assetType] = mappings;
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
syncedFiles[assetType] = mappings.map((m) => m.transformed);
|
|
199
|
-
}
|
|
243
|
+
syncedFiles[assetType] = units.map((u) => u.transformed ?? u.name);
|
|
200
244
|
}
|
|
201
245
|
return {
|
|
202
246
|
packageName,
|
|
@@ -206,11 +250,32 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
206
250
|
};
|
|
207
251
|
}
|
|
208
252
|
else {
|
|
209
|
-
const tag = options.ref ?? buildVersionTag(packageName, packageInfo.version);
|
|
210
253
|
const assetPath = buildAssetPath(packageInfo.claude.assetPath);
|
|
211
|
-
|
|
254
|
+
const useLocalSource = options.ref
|
|
255
|
+
? { available: false }
|
|
256
|
+
: canUseLocalSource(packageName, packageInfo.version, assetPath, cwd);
|
|
212
257
|
const assetTypes = getAssetTypes(packageInfo.claude);
|
|
213
|
-
|
|
258
|
+
let assetFiles;
|
|
259
|
+
let isLocalSource;
|
|
260
|
+
if (useLocalSource.available && useLocalSource.docsPath) {
|
|
261
|
+
isLocalSource = true;
|
|
262
|
+
logger.step('Using', 'local docs from node_modules');
|
|
263
|
+
assetFiles = await fetchLocalAssetFiles(useLocalSource.docsPath, assetTypes);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
if (!repoInfo) {
|
|
267
|
+
return {
|
|
268
|
+
packageName,
|
|
269
|
+
success: false,
|
|
270
|
+
skipped: true,
|
|
271
|
+
reason: `Package ${packageName} has no valid GitHub repository URL for remote fetch`,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
isLocalSource = false;
|
|
275
|
+
const tag = options.ref ?? buildVersionTag(packageName, packageInfo.version);
|
|
276
|
+
logger.step('Fetching', `asset list from GitHub (ref: ${tag})`);
|
|
277
|
+
assetFiles = await fetchAssetFiles(repoInfo, assetPath, tag, assetTypes);
|
|
278
|
+
}
|
|
214
279
|
let totalFiles = 0;
|
|
215
280
|
for (const assetType of assetTypes) {
|
|
216
281
|
totalFiles += (assetFiles[assetType] || []).length;
|
|
@@ -274,7 +339,14 @@ const syncPackage = async (packageName, options, cwd = process.cwd(), exclusions
|
|
|
274
339
|
if (filteredEntries.length === 0)
|
|
275
340
|
continue;
|
|
276
341
|
logger.step('Downloading', assetType);
|
|
277
|
-
|
|
342
|
+
let downloadedFiles;
|
|
343
|
+
if (isLocalSource && useLocalSource.docsPath) {
|
|
344
|
+
downloadedFiles = await downloadLocalAssetFiles(useLocalSource.docsPath, assetType, filteredEntries);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
const tag = options.ref ?? buildVersionTag(packageName, packageInfo.version);
|
|
348
|
+
downloadedFiles = await downloadAssetFiles(repoInfo, assetPath, assetType, filteredEntries, tag);
|
|
349
|
+
}
|
|
278
350
|
cleanAssetDir(destDir, packageName, assetType);
|
|
279
351
|
syncedFiles[assetType] = [];
|
|
280
352
|
for (const [fileName, content] of downloadedFiles) {
|
package/dist/core/syncMeta.cjs
CHANGED
|
@@ -9,7 +9,11 @@ const UNIFIED_META_PATH = constants.META_FILES.UNIFIED_SYNC_META;
|
|
|
9
9
|
const SCHEMA_VERSION = constants.SCHEMA_VERSIONS.UNIFIED_SYNC_META;
|
|
10
10
|
function readUnifiedSyncMeta(cwd) {
|
|
11
11
|
const metaPath = path.join(cwd, UNIFIED_META_PATH);
|
|
12
|
-
|
|
12
|
+
const meta = io.readJsonFile(metaPath);
|
|
13
|
+
if (meta && needsSkillUnitMigration(meta)) {
|
|
14
|
+
return migrateToSkillUnitSchema(meta);
|
|
15
|
+
}
|
|
16
|
+
return meta;
|
|
13
17
|
}
|
|
14
18
|
function writeUnifiedSyncMeta(cwd, meta) {
|
|
15
19
|
const metaPath = path.join(cwd, UNIFIED_META_PATH);
|
|
@@ -55,16 +59,14 @@ function createEmptyUnifiedMeta() {
|
|
|
55
59
|
packages: {},
|
|
56
60
|
};
|
|
57
61
|
}
|
|
58
|
-
function
|
|
62
|
+
function removeSkillUnitFromPackage(meta, prefix, assetType, skillName) {
|
|
59
63
|
const pkgInfo = meta.packages[prefix];
|
|
60
64
|
if (!pkgInfo) {
|
|
61
65
|
throw new Error(`Package ${prefix} not found in metadata`);
|
|
62
66
|
}
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
: f.original !== fileName && f.transformed !== fileName);
|
|
67
|
-
if (existingFiles.length === updatedFiles.length) {
|
|
67
|
+
const existingUnits = (pkgInfo.files[assetType] || []);
|
|
68
|
+
const updatedUnits = existingUnits.filter((u) => u.name !== skillName);
|
|
69
|
+
if (existingUnits.length === updatedUnits.length) {
|
|
68
70
|
return meta;
|
|
69
71
|
}
|
|
70
72
|
return {
|
|
@@ -76,18 +78,160 @@ function removeFileFromPackage(meta, prefix, assetType, fileName) {
|
|
|
76
78
|
...pkgInfo,
|
|
77
79
|
files: {
|
|
78
80
|
...pkgInfo.files,
|
|
79
|
-
[assetType]:
|
|
81
|
+
[assetType]: updatedUnits,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function updatePackageVersion(meta, prefix, newVersion) {
|
|
88
|
+
const pkgInfo = meta.packages[prefix];
|
|
89
|
+
if (!pkgInfo) {
|
|
90
|
+
throw new Error(`Package ${prefix} not found in metadata`);
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
...meta,
|
|
94
|
+
syncedAt: new Date().toISOString(),
|
|
95
|
+
packages: {
|
|
96
|
+
...meta.packages,
|
|
97
|
+
[prefix]: {
|
|
98
|
+
...pkgInfo,
|
|
99
|
+
version: newVersion,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function updatePackageFilesystemMeta(meta, prefix, assetType, updatedUnits) {
|
|
105
|
+
const pkgInfo = meta.packages[prefix];
|
|
106
|
+
if (!pkgInfo) {
|
|
107
|
+
throw new Error(`Package ${prefix} not found in metadata`);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
...meta,
|
|
111
|
+
syncedAt: new Date().toISOString(),
|
|
112
|
+
skillUnitFormat: constants.SCHEMA_VERSIONS.SKILL_UNIT_FORMAT,
|
|
113
|
+
packages: {
|
|
114
|
+
...meta.packages,
|
|
115
|
+
[prefix]: {
|
|
116
|
+
...pkgInfo,
|
|
117
|
+
files: {
|
|
118
|
+
...pkgInfo.files,
|
|
119
|
+
[assetType]: updatedUnits,
|
|
80
120
|
},
|
|
81
121
|
},
|
|
82
122
|
},
|
|
83
123
|
};
|
|
84
124
|
}
|
|
125
|
+
function needsSkillUnitMigration(meta) {
|
|
126
|
+
if (meta.skillUnitFormat === constants.SCHEMA_VERSIONS.SKILL_UNIT_FORMAT) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
for (const pkgInfo of Object.values(meta.packages)) {
|
|
130
|
+
for (const rawFiles of Object.values(pkgInfo.files)) {
|
|
131
|
+
const files = rawFiles;
|
|
132
|
+
if (!Array.isArray(files) || files.length === 0) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const first = files[0];
|
|
136
|
+
if (typeof first === 'string') {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
if (typeof first === 'object' &&
|
|
140
|
+
first !== null &&
|
|
141
|
+
'original' in first &&
|
|
142
|
+
'transformed' in first &&
|
|
143
|
+
!('isDirectory' in first)) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
if (typeof first === 'object' && first !== null && 'isDirectory' in first) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
function migrateToSkillUnitSchema(meta) {
|
|
154
|
+
const migratedPackages = {};
|
|
155
|
+
for (const [prefix, pkgInfo] of Object.entries(meta.packages)) {
|
|
156
|
+
const migratedFiles = {};
|
|
157
|
+
for (const [assetType, rawFiles] of Object.entries(pkgInfo.files)) {
|
|
158
|
+
const files = rawFiles;
|
|
159
|
+
if (!Array.isArray(files) || files.length === 0) {
|
|
160
|
+
migratedFiles[assetType] = [];
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const first = files[0];
|
|
164
|
+
if (typeof first === 'string') {
|
|
165
|
+
migratedFiles[assetType] = files.map((name) => ({
|
|
166
|
+
name,
|
|
167
|
+
isDirectory: false,
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
else if (typeof first === 'object' &&
|
|
171
|
+
first !== null &&
|
|
172
|
+
'original' in first &&
|
|
173
|
+
!('isDirectory' in first)) {
|
|
174
|
+
const fileMappings = files;
|
|
175
|
+
const groupedByDir = new Map();
|
|
176
|
+
const singleFiles = [];
|
|
177
|
+
for (const mapping of fileMappings) {
|
|
178
|
+
const slashIndex = mapping.original.indexOf('/');
|
|
179
|
+
if (slashIndex === -1) {
|
|
180
|
+
singleFiles.push({
|
|
181
|
+
name: mapping.original,
|
|
182
|
+
isDirectory: false,
|
|
183
|
+
transformed: mapping.transformed,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const dirName = mapping.original.substring(0, slashIndex);
|
|
188
|
+
const internalFile = mapping.original.substring(slashIndex + 1);
|
|
189
|
+
const transformedSlashIndex = mapping.transformed.indexOf('/');
|
|
190
|
+
const transformedDir = transformedSlashIndex !== -1
|
|
191
|
+
? mapping.transformed.substring(0, transformedSlashIndex)
|
|
192
|
+
: mapping.transformed;
|
|
193
|
+
if (!groupedByDir.has(dirName)) {
|
|
194
|
+
groupedByDir.set(dirName, { transformed: transformedDir, internalFiles: [] });
|
|
195
|
+
}
|
|
196
|
+
groupedByDir.get(dirName).internalFiles.push(internalFile);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const dirSkillUnits = [];
|
|
200
|
+
for (const [dirName, data] of groupedByDir.entries()) {
|
|
201
|
+
dirSkillUnits.push({
|
|
202
|
+
name: dirName,
|
|
203
|
+
isDirectory: true,
|
|
204
|
+
transformed: data.transformed,
|
|
205
|
+
internalFiles: data.internalFiles,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
migratedFiles[assetType] = [...singleFiles, ...dirSkillUnits];
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
migratedFiles[assetType] = files;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
migratedPackages[prefix] = {
|
|
215
|
+
...pkgInfo,
|
|
216
|
+
files: migratedFiles,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
...meta,
|
|
221
|
+
skillUnitFormat: constants.SCHEMA_VERSIONS.SKILL_UNIT_FORMAT,
|
|
222
|
+
packages: migratedPackages,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
85
225
|
|
|
86
226
|
exports.SCHEMA_VERSION = SCHEMA_VERSION;
|
|
87
227
|
exports.createEmptyUnifiedMeta = createEmptyUnifiedMeta;
|
|
228
|
+
exports.migrateToSkillUnitSchema = migrateToSkillUnitSchema;
|
|
229
|
+
exports.needsSkillUnitMigration = needsSkillUnitMigration;
|
|
88
230
|
exports.needsSyncUnified = needsSyncUnified;
|
|
89
231
|
exports.readUnifiedSyncMeta = readUnifiedSyncMeta;
|
|
90
|
-
exports.removeFileFromPackage = removeFileFromPackage;
|
|
91
232
|
exports.removePackageFromMeta = removePackageFromMeta;
|
|
233
|
+
exports.removeSkillUnitFromPackage = removeSkillUnitFromPackage;
|
|
234
|
+
exports.updatePackageFilesystemMeta = updatePackageFilesystemMeta;
|
|
92
235
|
exports.updatePackageInMeta = updatePackageInMeta;
|
|
236
|
+
exports.updatePackageVersion = updatePackageVersion;
|
|
93
237
|
exports.writeUnifiedSyncMeta = writeUnifiedSyncMeta;
|
package/dist/core/syncMeta.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { PackageSyncInfo, UnifiedSyncMeta } from '../utils/types.js';
|
|
1
|
+
import type { PackageSyncInfo, SkillUnit, UnifiedSyncMeta } from '../utils/types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Schema version for the unified metadata format
|
|
4
4
|
*/
|
|
5
|
-
export declare const SCHEMA_VERSION: "0.0.
|
|
5
|
+
export declare const SCHEMA_VERSION: "0.0.6";
|
|
6
6
|
/**
|
|
7
7
|
* Read unified sync metadata from .claude/.sync-meta.json
|
|
8
8
|
*
|
|
@@ -50,22 +50,26 @@ export declare function needsSyncUnified(meta: UnifiedSyncMeta | null, prefix: s
|
|
|
50
50
|
*/
|
|
51
51
|
export declare function createEmptyUnifiedMeta(): UnifiedSyncMeta;
|
|
52
52
|
/**
|
|
53
|
-
* Add a
|
|
54
|
-
*
|
|
55
|
-
* @param meta - Current unified metadata
|
|
56
|
-
* @param prefix - Package prefix (e.g., 'canard-schema-form')
|
|
57
|
-
* @param assetType - Asset type (e.g., 'commands', 'skills')
|
|
58
|
-
* @param fileName - File name to add
|
|
59
|
-
* @returns Updated metadata object
|
|
53
|
+
* Add a skill unit to a package's asset type in unified metadata
|
|
60
54
|
*/
|
|
61
|
-
export declare function
|
|
55
|
+
export declare function addSkillUnitToPackage(meta: UnifiedSyncMeta, prefix: string, assetType: string, unit: SkillUnit): UnifiedSyncMeta;
|
|
62
56
|
/**
|
|
63
|
-
* Remove a
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*
|
|
68
|
-
|
|
69
|
-
|
|
57
|
+
* Remove a skill unit from a package's asset type in unified metadata
|
|
58
|
+
*/
|
|
59
|
+
export declare function removeSkillUnitFromPackage(meta: UnifiedSyncMeta, prefix: string, assetType: string, skillName: string): UnifiedSyncMeta;
|
|
60
|
+
/**
|
|
61
|
+
* Update package version in unified metadata
|
|
62
|
+
*/
|
|
63
|
+
export declare function updatePackageVersion(meta: UnifiedSyncMeta, prefix: string, newVersion: string): UnifiedSyncMeta;
|
|
64
|
+
/**
|
|
65
|
+
* Update filesystem metadata for a package's asset type
|
|
66
|
+
*/
|
|
67
|
+
export declare function updatePackageFilesystemMeta(meta: UnifiedSyncMeta, prefix: string, assetType: string, updatedUnits: SkillUnit[]): UnifiedSyncMeta;
|
|
68
|
+
/**
|
|
69
|
+
* Check if unified metadata needs migration to SkillUnit format
|
|
70
|
+
*/
|
|
71
|
+
export declare function needsSkillUnitMigration(meta: UnifiedSyncMeta): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Migrate unified metadata from old format to SkillUnit format (in-memory only)
|
|
70
74
|
*/
|
|
71
|
-
export declare function
|
|
75
|
+
export declare function migrateToSkillUnitSchema(meta: UnifiedSyncMeta): UnifiedSyncMeta;
|