@slats/claude-assets-sync 0.1.3 → 0.2.0
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/README.md +111 -587
- package/bin/claude-sync.mjs +24 -0
- package/dist/@aileron/declare/index.d.ts +4 -4
- package/dist/claude-hashes.json +20 -0
- package/dist/commands/index.d.ts +1 -112
- package/dist/commands/runCli/index.d.ts +2 -0
- package/dist/commands/runCli/runCli.cjs +31 -0
- package/dist/commands/runCli/runCli.d.ts +10 -0
- package/dist/commands/runCli/runCli.mjs +29 -0
- package/dist/commands/runCli/type.d.ts +28 -0
- package/dist/commands/runCli/utils/injectOne.cjs +48 -0
- package/dist/commands/runCli/utils/injectOne.d.ts +3 -0
- package/dist/commands/runCli/utils/injectOne.mjs +46 -0
- package/dist/commands/runCli/utils/resolveScopeFlag.cjs +28 -0
- package/dist/commands/runCli/utils/resolveScopeFlag.d.ts +2 -0
- package/dist/commands/runCli/utils/resolveScopeFlag.mjs +26 -0
- package/dist/commands/runCli/utils/runInject.cjs +36 -0
- package/dist/commands/runCli/utils/runInject.d.ts +2 -0
- package/dist/commands/runCli/utils/runInject.mjs +34 -0
- package/dist/core/buildPlan/buildPlan.cjs +42 -0
- package/dist/core/buildPlan/buildPlan.d.ts +2 -0
- package/dist/core/buildPlan/buildPlan.mjs +40 -0
- package/dist/core/buildPlan/index.d.ts +2 -0
- package/dist/core/buildPlan/type.d.ts +32 -0
- package/dist/core/buildPlan/utils/toPosix.cjs +9 -0
- package/dist/core/buildPlan/utils/toPosix.d.ts +1 -0
- package/dist/core/buildPlan/utils/toPosix.mjs +7 -0
- package/dist/core/buildPlan/utils/walkFiles.cjs +25 -0
- package/dist/core/buildPlan/utils/walkFiles.d.ts +1 -0
- package/dist/core/buildPlan/utils/walkFiles.mjs +23 -0
- package/dist/core/hash/hash.cjs +30 -0
- package/dist/core/hash/hash.d.ts +4 -0
- package/dist/core/hash/hash.mjs +26 -0
- package/dist/core/hash/index.d.ts +1 -0
- package/dist/core/hashManifest/hashManifest.cjs +27 -0
- package/dist/core/hashManifest/hashManifest.d.ts +17 -0
- package/dist/core/hashManifest/hashManifest.mjs +23 -0
- package/dist/core/hashManifest/index.d.ts +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/injectDocs/index.d.ts +2 -0
- package/dist/core/injectDocs/injectDocs.cjs +43 -0
- package/dist/core/injectDocs/injectDocs.d.ts +2 -0
- package/dist/core/injectDocs/injectDocs.mjs +41 -0
- package/dist/core/injectDocs/type.d.ts +30 -0
- package/dist/core/injectDocs/utils/applyAction.cjs +21 -0
- package/dist/core/injectDocs/utils/applyAction.d.ts +2 -0
- package/dist/core/injectDocs/utils/applyAction.mjs +19 -0
- package/dist/core/injectDocs/utils/emitCiForceList.cjs +10 -0
- package/dist/core/injectDocs/utils/emitCiForceList.d.ts +2 -0
- package/dist/core/injectDocs/utils/emitCiForceList.mjs +8 -0
- package/dist/core/injectDocs/utils/printPlan.cjs +20 -0
- package/dist/core/injectDocs/utils/printPlan.d.ts +2 -0
- package/dist/core/injectDocs/utils/printPlan.mjs +18 -0
- package/dist/core/injectDocs/utils/summarize.cjs +27 -0
- package/dist/core/injectDocs/utils/summarize.d.ts +3 -0
- package/dist/core/injectDocs/utils/summarize.mjs +25 -0
- package/dist/core/scope/index.d.ts +1 -0
- package/dist/core/scope/scope.cjs +46 -0
- package/dist/core/scope/scope.d.ts +16 -0
- package/dist/core/scope/scope.mjs +41 -0
- package/dist/core/scope/utils/isDirectory.cjs +14 -0
- package/dist/core/scope/utils/isDirectory.d.ts +1 -0
- package/dist/core/scope/utils/isDirectory.mjs +12 -0
- package/dist/index.cjs +15 -9
- package/dist/index.d.ts +3 -5
- package/dist/index.mjs +7 -3
- package/dist/prompts/confirmForce.cjs +27 -0
- package/dist/prompts/confirmForce.d.ts +1 -0
- package/dist/prompts/confirmForce.mjs +25 -0
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/selectScope.cjs +30 -0
- package/dist/prompts/selectScope.d.ts +2 -0
- package/dist/prompts/selectScope.mjs +28 -0
- package/dist/utils/heartbeat.cjs +25 -0
- package/dist/utils/heartbeat.d.ts +16 -0
- package/dist/utils/heartbeat.mjs +23 -0
- package/dist/utils/logger.cjs +7 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.mjs +7 -0
- package/dist/utils/types.d.ts +1 -252
- package/dist/utils/version.cjs +2 -14
- package/dist/utils/version.d.ts +3 -53
- package/dist/utils/version.mjs +2 -13
- package/docs/bundle-size-decision.md +36 -0
- package/docs/claude/skills/claude-sync-applier/SKILL.md +195 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/claude-md-template.md +77 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/dependency-cruiser.md +126 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/gotchas.md +139 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/package-json-patches.md +130 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/reference-files.md +120 -0
- package/docs/claude/skills/claude-sync-applier/knowledge/smoke-tests.md +102 -0
- package/docs/consumer-integration.md +153 -0
- package/package.json +25 -17
- package/scripts/build-hashes.mjs +30 -0
- package/scripts/buildHashes.d.mts +15 -0
- package/scripts/buildHashes.mjs +82 -0
- package/scripts/claude-build-hashes.mjs +42 -0
- package/scripts/inject-version.js +112 -0
- package/dist/cli.cjs +0 -8
- package/dist/cli.d.ts +0 -1
- package/dist/cli.mjs +0 -7
- package/dist/commands/add.cjs +0 -80
- package/dist/commands/add.d.ts +0 -8
- package/dist/commands/add.mjs +0 -78
- package/dist/commands/list.cjs +0 -94
- package/dist/commands/list.d.ts +0 -15
- package/dist/commands/list.mjs +0 -91
- package/dist/commands/migrate.cjs +0 -9
- package/dist/commands/migrate.d.ts +0 -6
- package/dist/commands/migrate.mjs +0 -7
- package/dist/commands/remove.cjs +0 -127
- package/dist/commands/remove.d.ts +0 -6
- package/dist/commands/remove.mjs +0 -105
- package/dist/commands/status.cjs +0 -193
- package/dist/commands/status.d.ts +0 -6
- package/dist/commands/status.mjs +0 -171
- package/dist/commands/sync.cjs +0 -28
- package/dist/commands/sync.d.ts +0 -6
- package/dist/commands/sync.mjs +0 -26
- package/dist/commands/types.d.ts +0 -89
- package/dist/commands/update.cjs +0 -209
- package/dist/commands/update.d.ts +0 -29
- package/dist/commands/update.mjs +0 -206
- package/dist/components/add/AddCommand.cjs +0 -103
- package/dist/components/add/AddCommand.d.ts +0 -14
- package/dist/components/add/AddCommand.mjs +0 -101
- package/dist/components/add/BulkAddView.cjs +0 -165
- package/dist/components/add/BulkAddView.d.ts +0 -11
- package/dist/components/add/BulkAddView.mjs +0 -163
- package/dist/components/add/index.d.ts +0 -2
- package/dist/components/index.d.ts +0 -2
- package/dist/components/list/EditableTreeItem.d.ts +0 -13
- package/dist/components/list/ListCommand.cjs +0 -651
- package/dist/components/list/ListCommand.d.ts +0 -5
- package/dist/components/list/ListCommand.mjs +0 -649
- package/dist/components/list/SyncedPackageTree.d.ts +0 -14
- package/dist/components/list/index.d.ts +0 -10
- package/dist/components/list/types.d.ts +0 -14
- package/dist/components/primitives/Box.d.ts +0 -4
- package/dist/components/primitives/Spinner.d.ts +0 -6
- package/dist/components/primitives/Text.d.ts +0 -4
- package/dist/components/primitives/index.d.ts +0 -3
- package/dist/components/remove/RemoveConfirm.cjs +0 -18
- package/dist/components/remove/RemoveConfirm.d.ts +0 -11
- package/dist/components/remove/RemoveConfirm.mjs +0 -16
- package/dist/components/shared/Confirm.cjs +0 -30
- package/dist/components/shared/Confirm.d.ts +0 -8
- package/dist/components/shared/Confirm.mjs +0 -28
- package/dist/components/shared/MenuItem.cjs +0 -18
- package/dist/components/shared/MenuItem.d.ts +0 -7
- package/dist/components/shared/MenuItem.mjs +0 -16
- package/dist/components/shared/ProgressBar.d.ts +0 -7
- package/dist/components/shared/StepRunner.cjs +0 -58
- package/dist/components/shared/StepRunner.d.ts +0 -15
- package/dist/components/shared/StepRunner.mjs +0 -56
- package/dist/components/shared/Table.cjs +0 -19
- package/dist/components/shared/Table.d.ts +0 -8
- package/dist/components/shared/Table.mjs +0 -17
- package/dist/components/shared/index.d.ts +0 -6
- package/dist/components/status/PackageStatusCard.d.ts +0 -10
- package/dist/components/status/StatusDisplay.cjs +0 -26
- package/dist/components/status/StatusDisplay.d.ts +0 -23
- package/dist/components/status/StatusDisplay.mjs +0 -24
- package/dist/components/status/StatusTreeNode.cjs +0 -40
- package/dist/components/status/StatusTreeNode.d.ts +0 -15
- package/dist/components/status/StatusTreeNode.mjs +0 -38
- package/dist/components/status/index.d.ts +0 -6
- package/dist/components/tree/AssetTreeNode.cjs +0 -54
- package/dist/components/tree/AssetTreeNode.d.ts +0 -12
- package/dist/components/tree/AssetTreeNode.mjs +0 -52
- package/dist/components/tree/TreeSelect.cjs +0 -129
- package/dist/components/tree/TreeSelect.d.ts +0 -12
- package/dist/components/tree/TreeSelect.mjs +0 -127
- package/dist/components/tree/index.d.ts +0 -4
- package/dist/core/assetStructure.cjs +0 -30
- package/dist/core/assetStructure.d.ts +0 -36
- package/dist/core/assetStructure.mjs +0 -27
- package/dist/core/cli.cjs +0 -106
- package/dist/core/cli.d.ts +0 -9
- package/dist/core/cli.mjs +0 -103
- package/dist/core/constants.cjs +0 -28
- package/dist/core/constants.d.ts +0 -94
- package/dist/core/constants.mjs +0 -21
- package/dist/core/filesystem.cjs +0 -98
- package/dist/core/filesystem.d.ts +0 -94
- package/dist/core/filesystem.mjs +0 -88
- package/dist/core/github.cjs +0 -115
- package/dist/core/github.d.ts +0 -61
- package/dist/core/github.mjs +0 -107
- package/dist/core/io.cjs +0 -46
- package/dist/core/io.d.ts +0 -40
- package/dist/core/io.mjs +0 -39
- package/dist/core/listOperations.cjs +0 -228
- package/dist/core/listOperations.d.ts +0 -43
- package/dist/core/listOperations.mjs +0 -205
- package/dist/core/localSource.cjs +0 -126
- package/dist/core/localSource.d.ts +0 -33
- package/dist/core/localSource.mjs +0 -120
- package/dist/core/migration.cjs +0 -201
- package/dist/core/migration.d.ts +0 -57
- package/dist/core/migration.mjs +0 -198
- package/dist/core/packageScanner.cjs +0 -360
- package/dist/core/packageScanner.d.ts +0 -22
- package/dist/core/packageScanner.mjs +0 -356
- package/dist/core/sync.cjs +0 -400
- package/dist/core/sync.d.ts +0 -21
- package/dist/core/sync.mjs +0 -397
- package/dist/core/syncMeta.cjs +0 -242
- package/dist/core/syncMeta.d.ts +0 -75
- package/dist/core/syncMeta.mjs +0 -229
- package/dist/utils/dependencies.cjs +0 -57
- package/dist/utils/dependencies.d.ts +0 -10
- package/dist/utils/dependencies.mjs +0 -34
- package/dist/utils/nameTransform.cjs +0 -13
- package/dist/utils/nameTransform.d.ts +0 -65
- package/dist/utils/nameTransform.mjs +0 -11
- package/dist/utils/package.cjs +0 -170
- package/dist/utils/package.d.ts +0 -105
- package/dist/utils/package.mjs +0 -157
- package/dist/utils/packageName.cjs +0 -24
- package/dist/utils/packageName.d.ts +0 -32
- package/dist/utils/packageName.mjs +0 -21
- package/dist/utils/paths.cjs +0 -18
- package/dist/utils/paths.d.ts +0 -55
- package/dist/utils/paths.mjs +0 -15
- package/dist/version.cjs +0 -5
- package/dist/version.d.ts +0 -5
- package/dist/version.mjs +0 -3
package/dist/core/migration.d.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Result of migration operation
|
|
3
|
-
*/
|
|
4
|
-
export interface MigrationResult {
|
|
5
|
-
/** Whether migration completed successfully */
|
|
6
|
-
success: boolean;
|
|
7
|
-
/** List of package names that were migrated */
|
|
8
|
-
migratedPackages: string[];
|
|
9
|
-
/** List of errors encountered during migration */
|
|
10
|
-
errors?: string[];
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Check if migration from nested to flat structure is needed
|
|
14
|
-
* Scans for legacy nested directory patterns: .claude/{commands,skills}/@scope/package/
|
|
15
|
-
*
|
|
16
|
-
* @param cwd - Current working directory (project root)
|
|
17
|
-
* @returns true if legacy nested directories exist
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```ts
|
|
21
|
-
* if (needsMigration(process.cwd())) {
|
|
22
|
-
* console.log('Legacy structure detected, migration recommended');
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export declare function needsMigration(cwd: string): boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Migrate from legacy nested structure to flat structure
|
|
29
|
-
*
|
|
30
|
-
* Process:
|
|
31
|
-
* 1. Scan .claude/{commands,skills}/@scope/package/ directories
|
|
32
|
-
* 2. Read legacy .sync-meta.json files from each package
|
|
33
|
-
* 3. Copy files to flat structure with name prefixes (scope-package_filename.md)
|
|
34
|
-
* 4. Create or update unified .sync-meta.json
|
|
35
|
-
* 5. Remove empty legacy directories (if not dry-run)
|
|
36
|
-
*
|
|
37
|
-
* @param cwd - Current working directory (project root)
|
|
38
|
-
* @param options - Migration options
|
|
39
|
-
* @param options.dryRun - If true, only simulate migration without making changes
|
|
40
|
-
* @returns Migration result with success status and list of migrated packages
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```ts
|
|
44
|
-
* // Preview migration without making changes
|
|
45
|
-
* const preview = await migrateToFlat(process.cwd(), { dryRun: true });
|
|
46
|
-
* console.log(`Would migrate ${preview.migratedPackages.length} packages`);
|
|
47
|
-
*
|
|
48
|
-
* // Perform actual migration
|
|
49
|
-
* const result = await migrateToFlat(process.cwd(), { dryRun: false });
|
|
50
|
-
* if (result.success) {
|
|
51
|
-
* console.log(`Successfully migrated: ${result.migratedPackages.join(', ')}`);
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export declare function migrateToFlat(cwd: string, options?: {
|
|
56
|
-
dryRun?: boolean;
|
|
57
|
-
}): Promise<MigrationResult>;
|
package/dist/core/migration.mjs
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { existsSync, readdirSync, statSync, readFileSync, rmSync } from 'node:fs';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { toFlatFileName } from '../utils/nameTransform.mjs';
|
|
4
|
-
import { packageNameToPrefix } from '../utils/packageName.mjs';
|
|
5
|
-
import { writeFlatAssetFile } from './filesystem.mjs';
|
|
6
|
-
import { readUnifiedSyncMeta, createEmptyUnifiedMeta, updatePackageInMeta, writeUnifiedSyncMeta } from './syncMeta.mjs';
|
|
7
|
-
|
|
8
|
-
function needsMigration(cwd) {
|
|
9
|
-
const assetTypes = ['commands', 'skills'];
|
|
10
|
-
for (const assetType of assetTypes) {
|
|
11
|
-
const assetDir = join(cwd, '.claude', assetType);
|
|
12
|
-
if (!existsSync(assetDir)) {
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
try {
|
|
16
|
-
const entries = readdirSync(assetDir);
|
|
17
|
-
for (const entry of entries) {
|
|
18
|
-
if (entry.startsWith('@')) {
|
|
19
|
-
const scopeDir = join(assetDir, entry);
|
|
20
|
-
if (statSync(scopeDir).isDirectory()) {
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
console.error(`Error scanning ${assetDir}:`, error);
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
async function migrateToFlat(cwd, options = {}) {
|
|
34
|
-
const { dryRun = false } = options;
|
|
35
|
-
const migratedPackages = [];
|
|
36
|
-
const errors = [];
|
|
37
|
-
console.log(`\n🔄 Starting migration to flat structure${dryRun ? ' (DRY RUN)' : ''}...`);
|
|
38
|
-
let unifiedMeta = readUnifiedSyncMeta(cwd);
|
|
39
|
-
if (!unifiedMeta) {
|
|
40
|
-
console.log('📝 Creating new unified sync metadata');
|
|
41
|
-
unifiedMeta = createEmptyUnifiedMeta();
|
|
42
|
-
}
|
|
43
|
-
const assetTypes = ['commands', 'skills'];
|
|
44
|
-
const legacyDirs = [];
|
|
45
|
-
for (const assetType of assetTypes) {
|
|
46
|
-
const assetDir = join(cwd, '.claude', assetType);
|
|
47
|
-
if (!existsSync(assetDir)) {
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
console.log(`\n📂 Scanning ${assetType}...`);
|
|
51
|
-
try {
|
|
52
|
-
const scopeDirs = readdirSync(assetDir).filter((entry) => {
|
|
53
|
-
const fullPath = join(assetDir, entry);
|
|
54
|
-
return entry.startsWith('@') && statSync(fullPath).isDirectory();
|
|
55
|
-
});
|
|
56
|
-
for (const scopeDir of scopeDirs) {
|
|
57
|
-
const scopePath = join(assetDir, scopeDir);
|
|
58
|
-
const packageDirs = readdirSync(scopePath).filter((entry) => {
|
|
59
|
-
const fullPath = join(scopePath, entry);
|
|
60
|
-
return statSync(fullPath).isDirectory();
|
|
61
|
-
});
|
|
62
|
-
for (const packageDir of packageDirs) {
|
|
63
|
-
const packagePath = join(scopePath, packageDir);
|
|
64
|
-
const packageName = `${scopeDir}/${packageDir}`;
|
|
65
|
-
console.log(` 📦 Processing ${packageName}...`);
|
|
66
|
-
try {
|
|
67
|
-
const metaPath = join(packagePath, '.sync-meta.json');
|
|
68
|
-
let legacyMeta = null;
|
|
69
|
-
if (existsSync(metaPath)) {
|
|
70
|
-
const metaContent = readFileSync(metaPath, 'utf-8');
|
|
71
|
-
legacyMeta = JSON.parse(metaContent);
|
|
72
|
-
}
|
|
73
|
-
if (!legacyMeta) {
|
|
74
|
-
console.log(` ⚠️ No .sync-meta.json found, skipping`);
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
const prefix = packageNameToPrefix(packageName);
|
|
78
|
-
const commandUnits = [];
|
|
79
|
-
const skillUnits = [];
|
|
80
|
-
for (const fileName of legacyMeta.files) {
|
|
81
|
-
const sourcePath = join(packagePath, fileName);
|
|
82
|
-
if (!existsSync(sourcePath)) {
|
|
83
|
-
console.log(` ⚠️ File not found: ${fileName}`);
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
if (assetType === 'commands') {
|
|
87
|
-
if (!dryRun) {
|
|
88
|
-
const content = readFileSync(sourcePath, 'utf-8');
|
|
89
|
-
writeFlatAssetFile(cwd, assetType, fileName, content);
|
|
90
|
-
console.log(` ✅ Migrated: ${fileName}`);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
console.log(` 🔍 Would migrate: ${fileName}`);
|
|
94
|
-
}
|
|
95
|
-
commandUnits.push({ name: fileName, isDirectory: false });
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
const flatFileName = toFlatFileName(prefix, fileName);
|
|
99
|
-
if (!dryRun) {
|
|
100
|
-
const content = readFileSync(sourcePath, 'utf-8');
|
|
101
|
-
writeFlatAssetFile(cwd, assetType, flatFileName, content);
|
|
102
|
-
console.log(` ✅ Migrated: ${fileName} → ${flatFileName}`);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
console.log(` 🔍 Would migrate: ${fileName} → ${flatFileName}`);
|
|
106
|
-
}
|
|
107
|
-
skillUnits.push({
|
|
108
|
-
name: fileName,
|
|
109
|
-
isDirectory: false,
|
|
110
|
-
transformed: flatFileName,
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
const packageInfo = {
|
|
115
|
-
originalName: packageName,
|
|
116
|
-
version: legacyMeta.version,
|
|
117
|
-
files: {
|
|
118
|
-
commands: assetType === 'commands' ? commandUnits : [],
|
|
119
|
-
skills: assetType === 'skills' ? skillUnits : [],
|
|
120
|
-
agents: [],
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
if (unifiedMeta.packages[prefix]) {
|
|
124
|
-
const existing = unifiedMeta.packages[prefix];
|
|
125
|
-
if (assetType === 'commands') {
|
|
126
|
-
packageInfo.files.skills = existing.files.skills;
|
|
127
|
-
packageInfo.files.agents = existing.files.agents;
|
|
128
|
-
}
|
|
129
|
-
else if (assetType === 'skills') {
|
|
130
|
-
packageInfo.files.commands = existing.files.commands;
|
|
131
|
-
packageInfo.files.agents = existing.files.agents;
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
packageInfo.files.commands = existing.files.commands;
|
|
135
|
-
packageInfo.files.skills = existing.files.skills;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
unifiedMeta = updatePackageInMeta(unifiedMeta, prefix, packageInfo);
|
|
139
|
-
migratedPackages.push(packageName);
|
|
140
|
-
legacyDirs.push(packagePath);
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
const errorMsg = `Failed to migrate ${packageName}: ${error}`;
|
|
144
|
-
console.error(` ❌ ${errorMsg}`);
|
|
145
|
-
errors.push(errorMsg);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
legacyDirs.push(scopePath);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
const errorMsg = `Error scanning ${assetType}: ${error}`;
|
|
153
|
-
console.error(`❌ ${errorMsg}`);
|
|
154
|
-
errors.push(errorMsg);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
if (!dryRun && migratedPackages.length > 0) {
|
|
158
|
-
writeUnifiedSyncMeta(cwd, unifiedMeta);
|
|
159
|
-
console.log(`\n💾 Updated unified sync metadata`);
|
|
160
|
-
}
|
|
161
|
-
if (!dryRun && legacyDirs.length > 0) {
|
|
162
|
-
console.log(`\n🧹 Cleaning up legacy directories...`);
|
|
163
|
-
for (const legacyDir of legacyDirs) {
|
|
164
|
-
try {
|
|
165
|
-
if (existsSync(legacyDir)) {
|
|
166
|
-
const entries = readdirSync(legacyDir);
|
|
167
|
-
const hasOnlyMeta = entries.length === 1 && entries[0] === '.sync-meta.json';
|
|
168
|
-
const isEmpty = entries.length === 0;
|
|
169
|
-
if (isEmpty || hasOnlyMeta) {
|
|
170
|
-
rmSync(legacyDir, { recursive: true, force: true });
|
|
171
|
-
console.log(` ✅ Removed: ${legacyDir}`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
console.error(` ⚠️ Failed to remove ${legacyDir}:`, error);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
console.log(`\n📊 Migration Summary:`);
|
|
181
|
-
console.log(` ✅ Migrated packages: ${migratedPackages.length}`);
|
|
182
|
-
if (errors.length > 0) {
|
|
183
|
-
console.log(` ❌ Errors: ${errors.length}`);
|
|
184
|
-
}
|
|
185
|
-
if (dryRun) {
|
|
186
|
-
console.log(`\n🔍 DRY RUN: No changes were made. Run without --dry-run to apply migration.`);
|
|
187
|
-
}
|
|
188
|
-
else if (migratedPackages.length > 0) {
|
|
189
|
-
console.log(`\n✨ Migration completed successfully!`);
|
|
190
|
-
}
|
|
191
|
-
return {
|
|
192
|
-
success: errors.length === 0,
|
|
193
|
-
migratedPackages,
|
|
194
|
-
errors: errors.length > 0 ? errors : undefined,
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export { migrateToFlat, needsMigration };
|
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var fs = require('node:fs');
|
|
4
|
-
var path = require('node:path');
|
|
5
|
-
var nameTransform = require('../utils/nameTransform.cjs');
|
|
6
|
-
var _package = require('../utils/package.cjs');
|
|
7
|
-
var constants = require('./constants.cjs');
|
|
8
|
-
var github = require('./github.cjs');
|
|
9
|
-
|
|
10
|
-
function readPackageJsonFromPath(packagePath) {
|
|
11
|
-
try {
|
|
12
|
-
const packageJsonPath = path.join(packagePath, 'package.json');
|
|
13
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
const content = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
17
|
-
const json = JSON.parse(content);
|
|
18
|
-
return {
|
|
19
|
-
name: json.name,
|
|
20
|
-
version: json.version,
|
|
21
|
-
repository: json.repository,
|
|
22
|
-
claude: json.claude,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
async function scanPackageAssets(packageName, options) {
|
|
30
|
-
const cwd = options.cwd ?? process.cwd();
|
|
31
|
-
if (options.local) {
|
|
32
|
-
return scanLocalAssets(packageName, cwd);
|
|
33
|
-
}
|
|
34
|
-
return scanRemoteAssets(packageName, cwd, options.ref);
|
|
35
|
-
}
|
|
36
|
-
async function scanLocalAssets(packageName, cwd) {
|
|
37
|
-
const packagePath = findLocalPackage(packageName, cwd);
|
|
38
|
-
if (!packagePath) {
|
|
39
|
-
throw new Error(`Package ${packageName} not found in local workspace`);
|
|
40
|
-
}
|
|
41
|
-
const pkgInfo = readPackageJsonFromPath(packagePath);
|
|
42
|
-
if (!pkgInfo) {
|
|
43
|
-
throw new Error(`Package ${packageName} not found in local workspace`);
|
|
44
|
-
}
|
|
45
|
-
const claudeConfig = _package.resolveClaudeConfig(pkgInfo.claude);
|
|
46
|
-
const assetPath = path.join(packagePath, claudeConfig.assetPath);
|
|
47
|
-
if (!fs.existsSync(assetPath)) {
|
|
48
|
-
throw new Error(`Asset path ${assetPath} does not exist`);
|
|
49
|
-
}
|
|
50
|
-
const trees = [];
|
|
51
|
-
for (const assetType of constants.DEFAULT_ASSET_TYPES) {
|
|
52
|
-
const assetDir = path.join(assetPath, assetType);
|
|
53
|
-
if (!fs.existsSync(assetDir)) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const tree = buildTreeFromLocalDir(assetType, assetDir, assetType);
|
|
57
|
-
if (tree.children && tree.children.length > 0) {
|
|
58
|
-
trees.push(tree);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return trees;
|
|
62
|
-
}
|
|
63
|
-
async function scanRemoteAssets(packageName, cwd, ref) {
|
|
64
|
-
const nodeModulesPath = _package.resolvePackagePath(packageName, cwd);
|
|
65
|
-
if (!nodeModulesPath) {
|
|
66
|
-
throw new Error(`Package ${packageName} not found`);
|
|
67
|
-
}
|
|
68
|
-
const pkgInfo = readPackageJsonFromPath(nodeModulesPath);
|
|
69
|
-
if (!pkgInfo) {
|
|
70
|
-
throw new Error(`Package ${packageName} not found`);
|
|
71
|
-
}
|
|
72
|
-
const claudeConfig = _package.resolveClaudeConfig(pkgInfo.claude);
|
|
73
|
-
const assetBasePath = claudeConfig.assetPath;
|
|
74
|
-
if (!ref) {
|
|
75
|
-
const localDocsPath = path.join(nodeModulesPath, assetBasePath);
|
|
76
|
-
if (fs.existsSync(localDocsPath)) {
|
|
77
|
-
const trees = [];
|
|
78
|
-
for (const assetType of constants.DEFAULT_ASSET_TYPES) {
|
|
79
|
-
const assetDir = path.join(localDocsPath, assetType);
|
|
80
|
-
if (!fs.existsSync(assetDir))
|
|
81
|
-
continue;
|
|
82
|
-
const tree = buildTreeFromLocalDir(assetType, assetDir, assetType);
|
|
83
|
-
if (tree.children && tree.children.length > 0) {
|
|
84
|
-
trees.push(tree);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (trees.length > 0)
|
|
88
|
-
return trees;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (!pkgInfo.repository) {
|
|
92
|
-
throw new Error(`Package ${packageName} has no repository field`);
|
|
93
|
-
}
|
|
94
|
-
const repoInfo = _package.parseGitHubRepo(pkgInfo.repository);
|
|
95
|
-
if (!repoInfo) {
|
|
96
|
-
throw new Error(`Invalid GitHub repository URL in package ${packageName}`);
|
|
97
|
-
}
|
|
98
|
-
const tag = ref ?? 'HEAD';
|
|
99
|
-
const trees = [];
|
|
100
|
-
for (const assetType of constants.DEFAULT_ASSET_TYPES) {
|
|
101
|
-
const assetPath = repoInfo.directory
|
|
102
|
-
? `${repoInfo.directory}/${assetBasePath}/${assetType}`
|
|
103
|
-
: `${assetBasePath}/${assetType}`;
|
|
104
|
-
try {
|
|
105
|
-
const entries = await github.fetchDirectoryContents(repoInfo, assetPath, tag);
|
|
106
|
-
if (entries && entries.length > 0) {
|
|
107
|
-
const dirContentsMap = new Map();
|
|
108
|
-
for (const entry of entries) {
|
|
109
|
-
if (entry.type === 'dir') {
|
|
110
|
-
const dirEntries = await github.fetchDirectoryContents(repoInfo, `${assetPath}/${entry.name}`, tag);
|
|
111
|
-
if (dirEntries) {
|
|
112
|
-
dirContentsMap.set(entry.name, dirEntries);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const tree = buildTreeFromGitHubEntries(assetType, entries, assetType, dirContentsMap);
|
|
117
|
-
if (tree.children && tree.children.length > 0) {
|
|
118
|
-
trees.push(tree);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
catch {
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return trees;
|
|
127
|
-
}
|
|
128
|
-
function scanDirectoryRecursive(dirPath, prefix) {
|
|
129
|
-
const results = [];
|
|
130
|
-
try {
|
|
131
|
-
const entries = fs.readdirSync(dirPath);
|
|
132
|
-
for (const entry of entries) {
|
|
133
|
-
const fullPath = path.join(dirPath, entry);
|
|
134
|
-
const relativePath = prefix ? `${prefix}/${entry}` : entry;
|
|
135
|
-
const stat = fs.statSync(fullPath);
|
|
136
|
-
if (stat.isDirectory()) {
|
|
137
|
-
results.push(...scanDirectoryRecursive(fullPath, relativePath));
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
results.push(relativePath);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
catch {
|
|
145
|
-
}
|
|
146
|
-
return results;
|
|
147
|
-
}
|
|
148
|
-
function buildTreeFromLocalDir(label, dirPath, basePath) {
|
|
149
|
-
const entries = fs.readdirSync(dirPath);
|
|
150
|
-
const children = [];
|
|
151
|
-
for (const entry of entries) {
|
|
152
|
-
const fullPath = path.join(dirPath, entry);
|
|
153
|
-
const stat = fs.statSync(fullPath);
|
|
154
|
-
const relativePath = path.join(basePath, entry);
|
|
155
|
-
if (stat.isDirectory()) {
|
|
156
|
-
const isSkill = fs.existsSync(path.join(fullPath, 'SKILL.md')) ||
|
|
157
|
-
fs.existsSync(path.join(fullPath, 'Skill.md'));
|
|
158
|
-
if (isSkill) {
|
|
159
|
-
const internalFiles = scanDirectoryRecursive(fullPath, '');
|
|
160
|
-
const internalChildren = internalFiles.map((f) => ({
|
|
161
|
-
id: `${relativePath}/${f}`,
|
|
162
|
-
label: f,
|
|
163
|
-
path: `${relativePath}/${f}`,
|
|
164
|
-
type: 'file',
|
|
165
|
-
selected: true,
|
|
166
|
-
expanded: false,
|
|
167
|
-
disabled: true,
|
|
168
|
-
}));
|
|
169
|
-
children.push({
|
|
170
|
-
id: relativePath,
|
|
171
|
-
label: entry,
|
|
172
|
-
path: relativePath,
|
|
173
|
-
type: 'skill-directory',
|
|
174
|
-
children: internalChildren,
|
|
175
|
-
viewOnly: true,
|
|
176
|
-
selected: true,
|
|
177
|
-
expanded: false,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
const subTree = buildTreeFromLocalDir(entry, fullPath, relativePath);
|
|
182
|
-
if (subTree.children && subTree.children.length > 0) {
|
|
183
|
-
children.push(subTree);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
children.push({
|
|
189
|
-
id: relativePath,
|
|
190
|
-
label: entry,
|
|
191
|
-
path: relativePath,
|
|
192
|
-
type: 'file',
|
|
193
|
-
selected: true,
|
|
194
|
-
expanded: false,
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
return {
|
|
199
|
-
id: basePath,
|
|
200
|
-
label,
|
|
201
|
-
path: basePath,
|
|
202
|
-
type: 'directory',
|
|
203
|
-
children,
|
|
204
|
-
selected: true,
|
|
205
|
-
expanded: true,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
function buildTreeFromGitHubEntries(label, entries, basePath, dirContentsMap) {
|
|
209
|
-
const children = [];
|
|
210
|
-
for (const entry of entries) {
|
|
211
|
-
if (entry.type === 'file') {
|
|
212
|
-
children.push({
|
|
213
|
-
id: entry.path,
|
|
214
|
-
label: entry.name,
|
|
215
|
-
path: entry.path,
|
|
216
|
-
type: 'file',
|
|
217
|
-
selected: true,
|
|
218
|
-
expanded: false,
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
else if (entry.type === 'dir') {
|
|
222
|
-
const dirEntries = dirContentsMap?.get(entry.name);
|
|
223
|
-
const hasSkillMd = dirEntries ? isDirectorySkill(dirEntries) : false;
|
|
224
|
-
if (hasSkillMd) {
|
|
225
|
-
const skillPath = `${basePath}/${entry.name}`;
|
|
226
|
-
const internalChildren = dirEntries
|
|
227
|
-
? dirEntries.map((de) => ({
|
|
228
|
-
id: `${skillPath}/${de.name}`,
|
|
229
|
-
label: de.name,
|
|
230
|
-
path: `${skillPath}/${de.name}`,
|
|
231
|
-
type: 'file',
|
|
232
|
-
selected: true,
|
|
233
|
-
expanded: false,
|
|
234
|
-
disabled: true,
|
|
235
|
-
}))
|
|
236
|
-
: [];
|
|
237
|
-
children.push({
|
|
238
|
-
id: skillPath,
|
|
239
|
-
label: entry.name,
|
|
240
|
-
path: skillPath,
|
|
241
|
-
type: 'skill-directory',
|
|
242
|
-
children: internalChildren,
|
|
243
|
-
viewOnly: true,
|
|
244
|
-
selected: true,
|
|
245
|
-
expanded: false,
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
else if (dirEntries && dirEntries.length > 0) {
|
|
249
|
-
const subTree = buildTreeFromGitHubEntries(entry.name, dirEntries, `${basePath}/${entry.name}`);
|
|
250
|
-
if (subTree.children && subTree.children.length > 0) {
|
|
251
|
-
children.push(subTree);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
return {
|
|
257
|
-
id: basePath,
|
|
258
|
-
label,
|
|
259
|
-
path: basePath,
|
|
260
|
-
type: 'directory',
|
|
261
|
-
children,
|
|
262
|
-
selected: true,
|
|
263
|
-
expanded: true,
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
function isDirectorySkill(entries) {
|
|
267
|
-
return entries.some((entry) => entry.type === 'file' &&
|
|
268
|
-
(entry.name === 'SKILL.md' || entry.name === 'Skill.md'));
|
|
269
|
-
}
|
|
270
|
-
function findLocalPackage(packageName, cwd) {
|
|
271
|
-
const monorepoRoot = findMonorepoRoot(cwd);
|
|
272
|
-
const searchRoot = monorepoRoot || cwd;
|
|
273
|
-
const packagesDir = path.join(searchRoot, 'packages');
|
|
274
|
-
if (fs.existsSync(packagesDir)) {
|
|
275
|
-
const found = searchPackagesRecursively(packagesDir, packageName);
|
|
276
|
-
if (found)
|
|
277
|
-
return found;
|
|
278
|
-
}
|
|
279
|
-
const nodeModulesPath = path.join(searchRoot, 'node_modules', packageName);
|
|
280
|
-
if (fs.existsSync(nodeModulesPath)) {
|
|
281
|
-
return nodeModulesPath;
|
|
282
|
-
}
|
|
283
|
-
return null;
|
|
284
|
-
}
|
|
285
|
-
function findMonorepoRoot(startDir) {
|
|
286
|
-
let currentDir = startDir;
|
|
287
|
-
const root = '/';
|
|
288
|
-
while (currentDir !== root) {
|
|
289
|
-
const pkgJsonPath = path.join(currentDir, 'package.json');
|
|
290
|
-
if (fs.existsSync(pkgJsonPath)) {
|
|
291
|
-
try {
|
|
292
|
-
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
293
|
-
if (pkgJson.workspaces) {
|
|
294
|
-
return currentDir;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
catch {
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
currentDir = path.join(currentDir, '..');
|
|
301
|
-
}
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
function searchPackagesRecursively(dir, packageName) {
|
|
305
|
-
try {
|
|
306
|
-
const entries = fs.readdirSync(dir);
|
|
307
|
-
for (const entry of entries) {
|
|
308
|
-
const fullPath = path.join(dir, entry);
|
|
309
|
-
const stat = fs.statSync(fullPath);
|
|
310
|
-
if (stat.isDirectory()) {
|
|
311
|
-
const pkgJsonPath = path.join(fullPath, 'package.json');
|
|
312
|
-
if (fs.existsSync(pkgJsonPath)) {
|
|
313
|
-
const pkgInfo = readPackageJsonFromPath(fullPath);
|
|
314
|
-
if (pkgInfo && pkgInfo.name === packageName) {
|
|
315
|
-
return fullPath;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
const found = searchPackagesRecursively(fullPath, packageName);
|
|
319
|
-
if (found)
|
|
320
|
-
return found;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
catch {
|
|
325
|
-
}
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
function buildSkillUnitsFromTree(tree, prefix) {
|
|
329
|
-
if (!tree.children)
|
|
330
|
-
return [];
|
|
331
|
-
const units = [];
|
|
332
|
-
for (const child of tree.children) {
|
|
333
|
-
if (child.type === 'skill-directory') {
|
|
334
|
-
const internalFiles = child.children
|
|
335
|
-
? child.children.map((c) => c.label)
|
|
336
|
-
: [];
|
|
337
|
-
units.push({
|
|
338
|
-
name: child.label,
|
|
339
|
-
isDirectory: true,
|
|
340
|
-
transformed: nameTransform.toFlatFileName(prefix, child.label),
|
|
341
|
-
internalFiles,
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
else if (child.type === 'file') {
|
|
345
|
-
units.push({
|
|
346
|
-
name: child.label,
|
|
347
|
-
isDirectory: false,
|
|
348
|
-
transformed: nameTransform.toFlatFileName(prefix, child.label),
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
else if (child.type === 'directory') {
|
|
352
|
-
units.push(...buildSkillUnitsFromTree(child, prefix));
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
return units;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
exports.buildSkillUnitsFromTree = buildSkillUnitsFromTree;
|
|
359
|
-
exports.isDirectorySkill = isDirectorySkill;
|
|
360
|
-
exports.scanPackageAssets = scanPackageAssets;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { GitHubEntry, SkillUnit, TreeNode } from '../utils/types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Scan package assets from local workspace or GitHub
|
|
4
|
-
*
|
|
5
|
-
* @param packageName - Package name to scan
|
|
6
|
-
* @param options - Scan options
|
|
7
|
-
* @returns Tree structure of available assets
|
|
8
|
-
*/
|
|
9
|
-
export declare function scanPackageAssets(packageName: string, options: {
|
|
10
|
-
local: boolean;
|
|
11
|
-
ref?: string;
|
|
12
|
-
cwd?: string;
|
|
13
|
-
}): Promise<TreeNode[]>;
|
|
14
|
-
/**
|
|
15
|
-
* Check if entries represent a directory-based skill
|
|
16
|
-
*/
|
|
17
|
-
export declare function isDirectorySkill(entries: GitHubEntry[]): boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Convert a TreeNode asset-type subtree into SkillUnit[] for writing to meta.
|
|
20
|
-
* Used by both `add` and `list` commands when saving.
|
|
21
|
-
*/
|
|
22
|
-
export declare function buildSkillUnitsFromTree(tree: TreeNode, prefix: string): SkillUnit[];
|