@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.
Files changed (46) hide show
  1. package/dist/commands/add.cjs +2 -7
  2. package/dist/commands/add.mjs +2 -7
  3. package/dist/commands/index.d.ts +22 -0
  4. package/dist/commands/remove.cjs +6 -6
  5. package/dist/commands/remove.mjs +6 -6
  6. package/dist/commands/types.d.ts +2 -4
  7. package/dist/commands/update.cjs +178 -0
  8. package/dist/commands/update.d.ts +13 -0
  9. package/dist/commands/update.mjs +176 -0
  10. package/dist/components/add/AddCommand.cjs +11 -0
  11. package/dist/components/add/AddCommand.mjs +11 -0
  12. package/dist/components/list/ListCommand.cjs +65 -47
  13. package/dist/components/list/ListCommand.mjs +66 -48
  14. package/dist/components/status/StatusDisplay.cjs +4 -3
  15. package/dist/components/status/StatusDisplay.d.ts +2 -4
  16. package/dist/components/status/StatusDisplay.mjs +4 -3
  17. package/dist/components/tree/AssetTreeNode.cjs +21 -4
  18. package/dist/components/tree/AssetTreeNode.d.ts +1 -1
  19. package/dist/components/tree/AssetTreeNode.mjs +21 -4
  20. package/dist/components/tree/TreeSelect.cjs +14 -6
  21. package/dist/components/tree/TreeSelect.mjs +14 -6
  22. package/dist/core/cli.cjs +18 -0
  23. package/dist/core/cli.mjs +18 -0
  24. package/dist/core/constants.cjs +4 -1
  25. package/dist/core/constants.d.ts +8 -1
  26. package/dist/core/constants.mjs +4 -1
  27. package/dist/core/filesystem.cjs +7 -13
  28. package/dist/core/filesystem.mjs +7 -13
  29. package/dist/core/localSource.cjs +112 -0
  30. package/dist/core/localSource.d.ts +33 -0
  31. package/dist/core/localSource.mjs +106 -0
  32. package/dist/core/migration.cjs +10 -9
  33. package/dist/core/migration.mjs +10 -9
  34. package/dist/core/packageScanner.cjs +94 -1
  35. package/dist/core/packageScanner.d.ts +6 -1
  36. package/dist/core/packageScanner.mjs +94 -2
  37. package/dist/core/sync.cjs +118 -46
  38. package/dist/core/sync.mjs +119 -47
  39. package/dist/core/syncMeta.cjs +153 -9
  40. package/dist/core/syncMeta.d.ts +22 -18
  41. package/dist/core/syncMeta.mjs +149 -9
  42. package/dist/utils/types.d.ts +24 -7
  43. package/dist/version.cjs +1 -1
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.mjs +1 -1
  46. package/package.json +1 -1
@@ -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, buildVersionTag, buildAssetPath, getAssetTypes } from '../utils/package.mjs';
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
- logger.step('Fetching', `asset list from GitHub (ref: ${tag})`);
83
+ const useLocalSource = options.ref
84
+ ? { available: false }
85
+ : canUseLocalSource(packageName, packageInfo.version, assetPath, cwd);
59
86
  const assetTypes = getAssetTypes(packageInfo.claude);
60
- const assetFiles = await fetchAssetFiles(repoInfo, assetPath, tag, assetTypes);
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) => e.name);
138
+ fileMappings[assetType] = filteredEntries.map((e) => ({
139
+ name: e.name,
140
+ isDirectory: false,
141
+ }));
92
142
  }
93
143
  else {
94
- fileMappings[assetType] = filteredEntries.map((entry) => ({
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 mappings = fileMappings[assetType];
103
- if (!mappings || mappings.length === 0)
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
- mappings.forEach((fileName) => {
109
- logger.file('create', fileName);
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
- mappings.forEach((mapping) => {
115
- logger.file('create', mapping.transformed);
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 mappings = fileMappings[assetType];
122
- if (!mappings || mappings.length === 0)
169
+ const units = fileMappings[assetType];
170
+ if (!units || units.length === 0)
123
171
  continue;
124
- if (typeof mappings[0] === 'string') {
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
- const downloadedFiles = await downloadAssetFiles(repoInfo, assetPath, assetType, filteredEntries, tag);
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 mapping = mappings.find((m) => m.original === fileName);
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 mappings = fileMappings[assetType];
192
- if (!mappings || mappings.length === 0)
240
+ const units = fileMappings[assetType];
241
+ if (!units || units.length === 0)
193
242
  continue;
194
- if (typeof mappings[0] === 'string') {
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
- logger.step('Fetching', `asset list from GitHub (ref: ${tag})`);
254
+ const useLocalSource = options.ref
255
+ ? { available: false }
256
+ : canUseLocalSource(packageName, packageInfo.version, assetPath, cwd);
212
257
  const assetTypes = getAssetTypes(packageInfo.claude);
213
- const assetFiles = await fetchAssetFiles(repoInfo, assetPath, tag, assetTypes);
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
- const downloadedFiles = await downloadAssetFiles(repoInfo, assetPath, assetType, filteredEntries, tag);
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) {
@@ -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
- return io.readJsonFile(metaPath);
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 removeFileFromPackage(meta, prefix, assetType, fileName) {
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 existingFiles = pkgInfo.files[assetType] || [];
64
- const updatedFiles = existingFiles.filter((f) => typeof f === 'string'
65
- ? f !== fileName
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]: updatedFiles,
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;
@@ -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.4";
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 file to a package's asset type in unified metadata
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 addFileToPackage(meta: UnifiedSyncMeta, prefix: string, assetType: string, fileName: string): UnifiedSyncMeta;
55
+ export declare function addSkillUnitToPackage(meta: UnifiedSyncMeta, prefix: string, assetType: string, unit: SkillUnit): UnifiedSyncMeta;
62
56
  /**
63
- * Remove a file from a package's asset type in unified metadata
64
- *
65
- * @param meta - Current unified metadata
66
- * @param prefix - Package prefix (e.g., 'canard-schema-form')
67
- * @param assetType - Asset type (e.g., 'commands', 'skills')
68
- * @param fileName - File name to remove
69
- * @returns Updated metadata object
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 removeFileFromPackage(meta: UnifiedSyncMeta, prefix: string, assetType: string, fileName: string): UnifiedSyncMeta;
75
+ export declare function migrateToSkillUnitSchema(meta: UnifiedSyncMeta): UnifiedSyncMeta;