@slats/claude-assets-sync 0.1.4 → 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/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 +24 -16
- 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/commands/update.cjs
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var pc = require('picocolors');
|
|
4
|
-
var constants = require('../core/constants.cjs');
|
|
5
|
-
var packageScanner = require('../core/packageScanner.cjs');
|
|
6
|
-
var sync = require('../core/sync.cjs');
|
|
7
|
-
var syncMeta = require('../core/syncMeta.cjs');
|
|
8
|
-
var logger = require('../utils/logger.cjs');
|
|
9
|
-
var _package = require('../utils/package.cjs');
|
|
10
|
-
var packageName = require('../utils/packageName.cjs');
|
|
11
|
-
|
|
12
|
-
async function updatePackageVersionAndSync(prefix, meta, options, cwd) {
|
|
13
|
-
const packageInfo = meta.packages[prefix];
|
|
14
|
-
if (!packageInfo) {
|
|
15
|
-
throw new Error(`Package ${prefix} not found in metadata`);
|
|
16
|
-
}
|
|
17
|
-
const packageName = packageInfo.originalName;
|
|
18
|
-
const isLocal = options.local ?? packageInfo.local ?? false;
|
|
19
|
-
const currentPkgInfo = isLocal
|
|
20
|
-
? _package.readLocalPackageJson(packageName, cwd)
|
|
21
|
-
: _package.readPackageJson(packageName, cwd);
|
|
22
|
-
if (!currentPkgInfo) {
|
|
23
|
-
return { updatedMeta: meta, versionChanged: false };
|
|
24
|
-
}
|
|
25
|
-
const newVersion = currentPkgInfo.version;
|
|
26
|
-
const oldVersion = packageInfo.version;
|
|
27
|
-
if (newVersion === oldVersion) {
|
|
28
|
-
return { updatedMeta: meta, versionChanged: false, oldVersion, newVersion };
|
|
29
|
-
}
|
|
30
|
-
let updatedMeta = syncMeta.updatePackageVersion(meta, prefix, newVersion);
|
|
31
|
-
updatedMeta.syncedAt = new Date().toISOString();
|
|
32
|
-
{
|
|
33
|
-
const destDir = _package.findGitRoot(cwd) ?? cwd;
|
|
34
|
-
await sync.syncPackage(packageName, { force: true, dryRun: false, local: isLocal, ref: options.ref, flat: true }, cwd, packageInfo.exclusions, destDir);
|
|
35
|
-
}
|
|
36
|
-
return { updatedMeta, versionChanged: true, oldVersion, newVersion };
|
|
37
|
-
}
|
|
38
|
-
const runUpdateCommand = async (options, cwd = process.cwd()) => {
|
|
39
|
-
const destDir = _package.findGitRoot(cwd) ?? cwd;
|
|
40
|
-
const meta = syncMeta.readUnifiedSyncMeta(destDir);
|
|
41
|
-
if (!meta || Object.keys(meta.packages).length === 0) {
|
|
42
|
-
logger.logger.info('No packages synced yet. Use "sync" or "add" first.');
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const packagesToUpdate = [];
|
|
46
|
-
if (options.package) {
|
|
47
|
-
const prefix = packageName.packageNameToPrefix(options.package);
|
|
48
|
-
if (!meta.packages[prefix]) {
|
|
49
|
-
logger.logger.error(`Package ${options.package} is not synced.`);
|
|
50
|
-
process.exit(1);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
packagesToUpdate.push(prefix);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
packagesToUpdate.push(...Object.keys(meta.packages));
|
|
57
|
-
}
|
|
58
|
-
let updatedMeta = { ...meta };
|
|
59
|
-
let hasChanges = false;
|
|
60
|
-
for (const prefix of packagesToUpdate) {
|
|
61
|
-
const packageInfo = updatedMeta.packages[prefix];
|
|
62
|
-
const packageName = packageInfo.originalName;
|
|
63
|
-
console.log(pc.cyan(`\nUpdating ${packageName}...`));
|
|
64
|
-
const isLocal = options.local ?? packageInfo.local ?? false;
|
|
65
|
-
const currentPkgInfo = isLocal
|
|
66
|
-
? _package.readLocalPackageJson(packageName, cwd)
|
|
67
|
-
: _package.readPackageJson(packageName, cwd);
|
|
68
|
-
if (!currentPkgInfo) {
|
|
69
|
-
const location = isLocal ? 'workspace' : 'node_modules';
|
|
70
|
-
console.log(pc.yellow(` ⚠ Package not found in ${location}, skipping version update`));
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
const newVersion = currentPkgInfo.version;
|
|
74
|
-
if (newVersion !== packageInfo.version) {
|
|
75
|
-
if (options.dryRun) {
|
|
76
|
-
console.log(pc.gray(` [DRY RUN] Would update version: ${packageInfo.version} → ${newVersion}`));
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
updatedMeta = syncMeta.updatePackageVersion(updatedMeta, prefix, newVersion);
|
|
80
|
-
console.log(pc.green(` ✓ Version updated: ${packageInfo.version} → ${newVersion}`));
|
|
81
|
-
hasChanges = true;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
console.log(pc.gray(` Version unchanged: ${packageInfo.version}`));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
const scannedTrees = await packageScanner.scanPackageAssets(packageName, {
|
|
90
|
-
local: isLocal,
|
|
91
|
-
ref: options.ref,
|
|
92
|
-
cwd,
|
|
93
|
-
});
|
|
94
|
-
if (scannedTrees && scannedTrees.length > 0) {
|
|
95
|
-
for (const assetTypeTree of scannedTrees) {
|
|
96
|
-
const assetType = assetTypeTree.label;
|
|
97
|
-
const scannedUnits = packageScanner.buildSkillUnitsFromTree(assetTypeTree, prefix);
|
|
98
|
-
const currentUnits = packageInfo.files[assetType] || [];
|
|
99
|
-
const scannedNames = new Set(scannedUnits.map((u) => u.name));
|
|
100
|
-
const currentNames = new Set(currentUnits.map((u) => u.name));
|
|
101
|
-
const added = scannedUnits.filter((u) => !currentNames.has(u.name));
|
|
102
|
-
const removed = currentUnits.filter((u) => !scannedNames.has(u.name));
|
|
103
|
-
const unchanged = currentUnits.filter((u) => scannedNames.has(u.name));
|
|
104
|
-
if (added.length > 0 || removed.length > 0) {
|
|
105
|
-
const mergedUnits = [...unchanged, ...added];
|
|
106
|
-
if (options.dryRun) {
|
|
107
|
-
if (added.length > 0) {
|
|
108
|
-
console.log(pc.gray(` [DRY RUN] ${assetType}: ${added.length} new skill(s) found`));
|
|
109
|
-
for (const u of added) {
|
|
110
|
-
console.log(pc.gray(` + ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (removed.length > 0) {
|
|
114
|
-
console.log(pc.yellow(` [DRY RUN] ${assetType}: ${removed.length} skill(s) no longer in upstream`));
|
|
115
|
-
for (const u of removed) {
|
|
116
|
-
console.log(pc.yellow(` - ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
updatedMeta = syncMeta.updatePackageFilesystemMeta(updatedMeta, prefix, assetType, mergedUnits);
|
|
122
|
-
if (added.length > 0) {
|
|
123
|
-
console.log(pc.green(` ✓ ${assetType}: ${added.length} new skill(s) added to meta`));
|
|
124
|
-
for (const u of added) {
|
|
125
|
-
console.log(pc.green(` + ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
if (removed.length > 0) {
|
|
129
|
-
console.log(pc.yellow(` ⚠ ${assetType}: ${removed.length} skill(s) no longer in upstream (kept in meta)`));
|
|
130
|
-
for (const u of removed) {
|
|
131
|
-
console.log(pc.yellow(` - ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
hasChanges = true;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
let internalChanged = false;
|
|
139
|
-
const refreshedUnits = currentUnits.map((current) => {
|
|
140
|
-
const scanned = scannedUnits.find((s) => s.name === current.name);
|
|
141
|
-
if (scanned && scanned.isDirectory && current.isDirectory) {
|
|
142
|
-
const currentInternal = (current.internalFiles || [])
|
|
143
|
-
.sort()
|
|
144
|
-
.join(',');
|
|
145
|
-
const scannedInternal = (scanned.internalFiles || [])
|
|
146
|
-
.sort()
|
|
147
|
-
.join(',');
|
|
148
|
-
if (currentInternal !== scannedInternal) {
|
|
149
|
-
internalChanged = true;
|
|
150
|
-
return { ...current, internalFiles: scanned.internalFiles };
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return current;
|
|
154
|
-
});
|
|
155
|
-
if (internalChanged && !options.dryRun) {
|
|
156
|
-
updatedMeta = syncMeta.updatePackageFilesystemMeta(updatedMeta, prefix, assetType, refreshedUnits);
|
|
157
|
-
console.log(pc.green(` ✓ ${assetType}: internal file lists updated`));
|
|
158
|
-
hasChanges = true;
|
|
159
|
-
}
|
|
160
|
-
else if (internalChanged && options.dryRun) {
|
|
161
|
-
console.log(pc.gray(` [DRY RUN] ${assetType}: would update internal file lists`));
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
console.log(pc.gray(` ${assetType}: no changes`));
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
catch {
|
|
171
|
-
console.log(pc.yellow(` ⚠ Could not scan package assets, skipping filesystem update`));
|
|
172
|
-
}
|
|
173
|
-
if (options.sync && !options.dryRun) {
|
|
174
|
-
console.log(pc.cyan(` Syncing files...`));
|
|
175
|
-
try {
|
|
176
|
-
await sync.syncPackage(packageName, {
|
|
177
|
-
force: true,
|
|
178
|
-
dryRun: false,
|
|
179
|
-
local: isLocal,
|
|
180
|
-
ref: options.ref,
|
|
181
|
-
flat: true,
|
|
182
|
-
}, cwd, packageInfo.exclusions, destDir);
|
|
183
|
-
console.log(pc.green(` ✓ Files synced`));
|
|
184
|
-
}
|
|
185
|
-
catch (error) {
|
|
186
|
-
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
187
|
-
console.log(pc.red(` ✗ Sync failed: ${message}`));
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
else if (options.sync && options.dryRun) {
|
|
191
|
-
console.log(pc.gray(` [DRY RUN] Would re-sync files`));
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
if (hasChanges && !options.dryRun) {
|
|
195
|
-
updatedMeta.syncedAt = new Date().toISOString();
|
|
196
|
-
updatedMeta.skillUnitFormat = constants.SCHEMA_VERSIONS.SKILL_UNIT_FORMAT;
|
|
197
|
-
syncMeta.writeUnifiedSyncMeta(destDir, updatedMeta);
|
|
198
|
-
console.log(pc.green(`\n✓ Metadata updated`));
|
|
199
|
-
}
|
|
200
|
-
else if (options.dryRun) {
|
|
201
|
-
console.log(pc.gray(`\n[DRY RUN] No changes written`));
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
console.log(pc.gray(`\nNo changes needed`));
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
exports.runUpdateCommand = runUpdateCommand;
|
|
209
|
-
exports.updatePackageVersionAndSync = updatePackageVersionAndSync;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { UnifiedSyncMeta } from '../utils/types.js';
|
|
2
|
-
export interface UpdateCommandOptions {
|
|
3
|
-
package?: string;
|
|
4
|
-
local?: boolean;
|
|
5
|
-
ref?: string;
|
|
6
|
-
dryRun?: boolean;
|
|
7
|
-
sync?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface UpdatePackageResult {
|
|
10
|
-
updatedMeta: UnifiedSyncMeta;
|
|
11
|
-
versionChanged: boolean;
|
|
12
|
-
oldVersion?: string;
|
|
13
|
-
newVersion?: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Higher-level orchestration: read installed version, compare with meta, update if different,
|
|
17
|
-
* optionally re-sync files. Can be called from both CLI and interactive list UI.
|
|
18
|
-
*/
|
|
19
|
-
export declare function updatePackageVersionAndSync(prefix: string, meta: UnifiedSyncMeta, options: {
|
|
20
|
-
local?: boolean;
|
|
21
|
-
ref?: string;
|
|
22
|
-
sync?: boolean;
|
|
23
|
-
}, cwd: string): Promise<UpdatePackageResult>;
|
|
24
|
-
/**
|
|
25
|
-
* Run the update command
|
|
26
|
-
* @param options - Update command options
|
|
27
|
-
* @param cwd - Current working directory
|
|
28
|
-
*/
|
|
29
|
-
export declare const runUpdateCommand: (options: UpdateCommandOptions, cwd?: string) => Promise<void>;
|
package/dist/commands/update.mjs
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import pc from 'picocolors';
|
|
2
|
-
import { SCHEMA_VERSIONS } from '../core/constants.mjs';
|
|
3
|
-
import { scanPackageAssets, buildSkillUnitsFromTree } from '../core/packageScanner.mjs';
|
|
4
|
-
import { syncPackage } from '../core/sync.mjs';
|
|
5
|
-
import { readUnifiedSyncMeta, updatePackageVersion, updatePackageFilesystemMeta, writeUnifiedSyncMeta } from '../core/syncMeta.mjs';
|
|
6
|
-
import { logger } from '../utils/logger.mjs';
|
|
7
|
-
import { findGitRoot, readLocalPackageJson, readPackageJson } from '../utils/package.mjs';
|
|
8
|
-
import { packageNameToPrefix } from '../utils/packageName.mjs';
|
|
9
|
-
|
|
10
|
-
async function updatePackageVersionAndSync(prefix, meta, options, cwd) {
|
|
11
|
-
const packageInfo = meta.packages[prefix];
|
|
12
|
-
if (!packageInfo) {
|
|
13
|
-
throw new Error(`Package ${prefix} not found in metadata`);
|
|
14
|
-
}
|
|
15
|
-
const packageName = packageInfo.originalName;
|
|
16
|
-
const isLocal = options.local ?? packageInfo.local ?? false;
|
|
17
|
-
const currentPkgInfo = isLocal
|
|
18
|
-
? readLocalPackageJson(packageName, cwd)
|
|
19
|
-
: readPackageJson(packageName, cwd);
|
|
20
|
-
if (!currentPkgInfo) {
|
|
21
|
-
return { updatedMeta: meta, versionChanged: false };
|
|
22
|
-
}
|
|
23
|
-
const newVersion = currentPkgInfo.version;
|
|
24
|
-
const oldVersion = packageInfo.version;
|
|
25
|
-
if (newVersion === oldVersion) {
|
|
26
|
-
return { updatedMeta: meta, versionChanged: false, oldVersion, newVersion };
|
|
27
|
-
}
|
|
28
|
-
let updatedMeta = updatePackageVersion(meta, prefix, newVersion);
|
|
29
|
-
updatedMeta.syncedAt = new Date().toISOString();
|
|
30
|
-
{
|
|
31
|
-
const destDir = findGitRoot(cwd) ?? cwd;
|
|
32
|
-
await syncPackage(packageName, { force: true, dryRun: false, local: isLocal, ref: options.ref, flat: true }, cwd, packageInfo.exclusions, destDir);
|
|
33
|
-
}
|
|
34
|
-
return { updatedMeta, versionChanged: true, oldVersion, newVersion };
|
|
35
|
-
}
|
|
36
|
-
const runUpdateCommand = async (options, cwd = process.cwd()) => {
|
|
37
|
-
const destDir = findGitRoot(cwd) ?? cwd;
|
|
38
|
-
const meta = readUnifiedSyncMeta(destDir);
|
|
39
|
-
if (!meta || Object.keys(meta.packages).length === 0) {
|
|
40
|
-
logger.info('No packages synced yet. Use "sync" or "add" first.');
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
const packagesToUpdate = [];
|
|
44
|
-
if (options.package) {
|
|
45
|
-
const prefix = packageNameToPrefix(options.package);
|
|
46
|
-
if (!meta.packages[prefix]) {
|
|
47
|
-
logger.error(`Package ${options.package} is not synced.`);
|
|
48
|
-
process.exit(1);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
packagesToUpdate.push(prefix);
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
packagesToUpdate.push(...Object.keys(meta.packages));
|
|
55
|
-
}
|
|
56
|
-
let updatedMeta = { ...meta };
|
|
57
|
-
let hasChanges = false;
|
|
58
|
-
for (const prefix of packagesToUpdate) {
|
|
59
|
-
const packageInfo = updatedMeta.packages[prefix];
|
|
60
|
-
const packageName = packageInfo.originalName;
|
|
61
|
-
console.log(pc.cyan(`\nUpdating ${packageName}...`));
|
|
62
|
-
const isLocal = options.local ?? packageInfo.local ?? false;
|
|
63
|
-
const currentPkgInfo = isLocal
|
|
64
|
-
? readLocalPackageJson(packageName, cwd)
|
|
65
|
-
: readPackageJson(packageName, cwd);
|
|
66
|
-
if (!currentPkgInfo) {
|
|
67
|
-
const location = isLocal ? 'workspace' : 'node_modules';
|
|
68
|
-
console.log(pc.yellow(` ⚠ Package not found in ${location}, skipping version update`));
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
const newVersion = currentPkgInfo.version;
|
|
72
|
-
if (newVersion !== packageInfo.version) {
|
|
73
|
-
if (options.dryRun) {
|
|
74
|
-
console.log(pc.gray(` [DRY RUN] Would update version: ${packageInfo.version} → ${newVersion}`));
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
updatedMeta = updatePackageVersion(updatedMeta, prefix, newVersion);
|
|
78
|
-
console.log(pc.green(` ✓ Version updated: ${packageInfo.version} → ${newVersion}`));
|
|
79
|
-
hasChanges = true;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
console.log(pc.gray(` Version unchanged: ${packageInfo.version}`));
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
try {
|
|
87
|
-
const scannedTrees = await scanPackageAssets(packageName, {
|
|
88
|
-
local: isLocal,
|
|
89
|
-
ref: options.ref,
|
|
90
|
-
cwd,
|
|
91
|
-
});
|
|
92
|
-
if (scannedTrees && scannedTrees.length > 0) {
|
|
93
|
-
for (const assetTypeTree of scannedTrees) {
|
|
94
|
-
const assetType = assetTypeTree.label;
|
|
95
|
-
const scannedUnits = buildSkillUnitsFromTree(assetTypeTree, prefix);
|
|
96
|
-
const currentUnits = packageInfo.files[assetType] || [];
|
|
97
|
-
const scannedNames = new Set(scannedUnits.map((u) => u.name));
|
|
98
|
-
const currentNames = new Set(currentUnits.map((u) => u.name));
|
|
99
|
-
const added = scannedUnits.filter((u) => !currentNames.has(u.name));
|
|
100
|
-
const removed = currentUnits.filter((u) => !scannedNames.has(u.name));
|
|
101
|
-
const unchanged = currentUnits.filter((u) => scannedNames.has(u.name));
|
|
102
|
-
if (added.length > 0 || removed.length > 0) {
|
|
103
|
-
const mergedUnits = [...unchanged, ...added];
|
|
104
|
-
if (options.dryRun) {
|
|
105
|
-
if (added.length > 0) {
|
|
106
|
-
console.log(pc.gray(` [DRY RUN] ${assetType}: ${added.length} new skill(s) found`));
|
|
107
|
-
for (const u of added) {
|
|
108
|
-
console.log(pc.gray(` + ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (removed.length > 0) {
|
|
112
|
-
console.log(pc.yellow(` [DRY RUN] ${assetType}: ${removed.length} skill(s) no longer in upstream`));
|
|
113
|
-
for (const u of removed) {
|
|
114
|
-
console.log(pc.yellow(` - ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
updatedMeta = updatePackageFilesystemMeta(updatedMeta, prefix, assetType, mergedUnits);
|
|
120
|
-
if (added.length > 0) {
|
|
121
|
-
console.log(pc.green(` ✓ ${assetType}: ${added.length} new skill(s) added to meta`));
|
|
122
|
-
for (const u of added) {
|
|
123
|
-
console.log(pc.green(` + ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (removed.length > 0) {
|
|
127
|
-
console.log(pc.yellow(` ⚠ ${assetType}: ${removed.length} skill(s) no longer in upstream (kept in meta)`));
|
|
128
|
-
for (const u of removed) {
|
|
129
|
-
console.log(pc.yellow(` - ${u.name}${u.isDirectory ? '/' : ''}`));
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
hasChanges = true;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
let internalChanged = false;
|
|
137
|
-
const refreshedUnits = currentUnits.map((current) => {
|
|
138
|
-
const scanned = scannedUnits.find((s) => s.name === current.name);
|
|
139
|
-
if (scanned && scanned.isDirectory && current.isDirectory) {
|
|
140
|
-
const currentInternal = (current.internalFiles || [])
|
|
141
|
-
.sort()
|
|
142
|
-
.join(',');
|
|
143
|
-
const scannedInternal = (scanned.internalFiles || [])
|
|
144
|
-
.sort()
|
|
145
|
-
.join(',');
|
|
146
|
-
if (currentInternal !== scannedInternal) {
|
|
147
|
-
internalChanged = true;
|
|
148
|
-
return { ...current, internalFiles: scanned.internalFiles };
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return current;
|
|
152
|
-
});
|
|
153
|
-
if (internalChanged && !options.dryRun) {
|
|
154
|
-
updatedMeta = updatePackageFilesystemMeta(updatedMeta, prefix, assetType, refreshedUnits);
|
|
155
|
-
console.log(pc.green(` ✓ ${assetType}: internal file lists updated`));
|
|
156
|
-
hasChanges = true;
|
|
157
|
-
}
|
|
158
|
-
else if (internalChanged && options.dryRun) {
|
|
159
|
-
console.log(pc.gray(` [DRY RUN] ${assetType}: would update internal file lists`));
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
console.log(pc.gray(` ${assetType}: no changes`));
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
catch {
|
|
169
|
-
console.log(pc.yellow(` ⚠ Could not scan package assets, skipping filesystem update`));
|
|
170
|
-
}
|
|
171
|
-
if (options.sync && !options.dryRun) {
|
|
172
|
-
console.log(pc.cyan(` Syncing files...`));
|
|
173
|
-
try {
|
|
174
|
-
await syncPackage(packageName, {
|
|
175
|
-
force: true,
|
|
176
|
-
dryRun: false,
|
|
177
|
-
local: isLocal,
|
|
178
|
-
ref: options.ref,
|
|
179
|
-
flat: true,
|
|
180
|
-
}, cwd, packageInfo.exclusions, destDir);
|
|
181
|
-
console.log(pc.green(` ✓ Files synced`));
|
|
182
|
-
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
185
|
-
console.log(pc.red(` ✗ Sync failed: ${message}`));
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
else if (options.sync && options.dryRun) {
|
|
189
|
-
console.log(pc.gray(` [DRY RUN] Would re-sync files`));
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (hasChanges && !options.dryRun) {
|
|
193
|
-
updatedMeta.syncedAt = new Date().toISOString();
|
|
194
|
-
updatedMeta.skillUnitFormat = SCHEMA_VERSIONS.SKILL_UNIT_FORMAT;
|
|
195
|
-
writeUnifiedSyncMeta(destDir, updatedMeta);
|
|
196
|
-
console.log(pc.green(`\n✓ Metadata updated`));
|
|
197
|
-
}
|
|
198
|
-
else if (options.dryRun) {
|
|
199
|
-
console.log(pc.gray(`\n[DRY RUN] No changes written`));
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
console.log(pc.gray(`\nNo changes needed`));
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
export { runUpdateCommand, updatePackageVersionAndSync };
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var hook = require('@winglet/react-utils/hook');
|
|
5
|
-
var ink = require('ink');
|
|
6
|
-
var Spinner = require('ink-spinner');
|
|
7
|
-
var React = require('react');
|
|
8
|
-
var packageScanner = require('../../core/packageScanner.cjs');
|
|
9
|
-
var TreeSelect = require('../tree/TreeSelect.cjs');
|
|
10
|
-
|
|
11
|
-
const AddCommand = ({ packageName, local, ref, onComplete, onError, onCancel, }) => {
|
|
12
|
-
const [state, setState] = React.useState('scanning');
|
|
13
|
-
const [trees, setTrees] = React.useState([]);
|
|
14
|
-
const [error, setError] = React.useState(null);
|
|
15
|
-
const handleComplete = hook.useHandle(onComplete);
|
|
16
|
-
const handleError = hook.useHandle(onError);
|
|
17
|
-
const handleCancel = hook.useHandle(onCancel);
|
|
18
|
-
React.useEffect(() => {
|
|
19
|
-
const scan = async () => {
|
|
20
|
-
try {
|
|
21
|
-
setState('scanning');
|
|
22
|
-
const scanned = await packageScanner.scanPackageAssets(packageName, { local, ref });
|
|
23
|
-
setTrees(scanned);
|
|
24
|
-
setState('selecting');
|
|
25
|
-
}
|
|
26
|
-
catch (err) {
|
|
27
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
28
|
-
setError(error);
|
|
29
|
-
setState('error');
|
|
30
|
-
handleError(error);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
scan();
|
|
34
|
-
}, [packageName, local, ref, handleError]);
|
|
35
|
-
const handleSubmit = React.useCallback((selectedTrees) => {
|
|
36
|
-
setState('confirming');
|
|
37
|
-
const includedAssets = {};
|
|
38
|
-
const excludedAssets = {};
|
|
39
|
-
for (const tree of selectedTrees) {
|
|
40
|
-
const assetType = tree.label;
|
|
41
|
-
includedAssets[assetType] = [];
|
|
42
|
-
excludedAssets[assetType] = [];
|
|
43
|
-
if (tree.children) {
|
|
44
|
-
extractSelection(tree.children, includedAssets[assetType], excludedAssets[assetType]);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const selection = {
|
|
48
|
-
packageName,
|
|
49
|
-
source: local ? 'local' : 'npm',
|
|
50
|
-
ref,
|
|
51
|
-
includedAssets,
|
|
52
|
-
excludedAssets,
|
|
53
|
-
};
|
|
54
|
-
setState('done');
|
|
55
|
-
handleComplete(selection);
|
|
56
|
-
}, [packageName, local, ref, handleComplete]);
|
|
57
|
-
if (state === 'scanning') {
|
|
58
|
-
return (jsxRuntime.jsx(ink.Box, { children: jsxRuntime.jsxs(ink.Text, { color: "cyan", children: [jsxRuntime.jsx(Spinner, { type: "dots" }), " Scanning package assets..."] }) }));
|
|
59
|
-
}
|
|
60
|
-
if (state === 'error') {
|
|
61
|
-
return (jsxRuntime.jsx(ink.Box, { flexDirection: "column", children: jsxRuntime.jsxs(ink.Text, { color: "red", children: ["Error: ", error?.message] }) }));
|
|
62
|
-
}
|
|
63
|
-
if (state === 'selecting') {
|
|
64
|
-
return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsxs(ink.Text, { bold: true, children: ["Select assets to sync from ", packageName] }) }), jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Use \u2191/\u2193 to navigate, Space to toggle, \u2192/\u2190 to expand/collapse, Enter to confirm, Esc to cancel" }) }), jsxRuntime.jsx(TreeSelect.TreeSelect, { trees: trees, onSubmit: handleSubmit, onCancel: handleCancel })] }));
|
|
65
|
-
}
|
|
66
|
-
if (state === 'confirming' || state === 'done') {
|
|
67
|
-
return (jsxRuntime.jsx(ink.Box, { children: jsxRuntime.jsx(ink.Text, { color: "green", children: "\u2713 Selection confirmed" }) }));
|
|
68
|
-
}
|
|
69
|
-
return null;
|
|
70
|
-
};
|
|
71
|
-
function extractSelection(nodes, included, excluded) {
|
|
72
|
-
for (const node of nodes) {
|
|
73
|
-
if (node.disabled)
|
|
74
|
-
continue;
|
|
75
|
-
if (node.type === 'skill-directory') {
|
|
76
|
-
if (node.selected) {
|
|
77
|
-
included.push(node.path);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
excluded.push(node.path);
|
|
81
|
-
}
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
if (node.selected) {
|
|
85
|
-
included.push(node.path);
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
excluded.push(node.path);
|
|
89
|
-
}
|
|
90
|
-
if (node.children && hasPartialSelection(node)) {
|
|
91
|
-
extractSelection(node.children, included, excluded);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
function hasPartialSelection(node) {
|
|
96
|
-
if (!node.children || node.children.length === 0) {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
const selectedCount = node.children.filter((c) => c.selected).length;
|
|
100
|
-
return selectedCount > 0 && selectedCount < node.children.length;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
exports.AddCommand = AddCommand;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { AddCommandSelection } from '../../utils/types.js';
|
|
3
|
-
export interface AddCommandProps {
|
|
4
|
-
packageName: string;
|
|
5
|
-
local: boolean;
|
|
6
|
-
ref?: string;
|
|
7
|
-
onComplete: (selection: AddCommandSelection) => void;
|
|
8
|
-
onError: (error: Error) => void;
|
|
9
|
-
onCancel: () => void;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Add command flow component
|
|
13
|
-
*/
|
|
14
|
-
export declare const AddCommand: React.FC<AddCommandProps>;
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { useHandle } from '@winglet/react-utils/hook';
|
|
3
|
-
import { Box, Text } from 'ink';
|
|
4
|
-
import Spinner from 'ink-spinner';
|
|
5
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
6
|
-
import { scanPackageAssets } from '../../core/packageScanner.mjs';
|
|
7
|
-
import { TreeSelect } from '../tree/TreeSelect.mjs';
|
|
8
|
-
|
|
9
|
-
const AddCommand = ({ packageName, local, ref, onComplete, onError, onCancel, }) => {
|
|
10
|
-
const [state, setState] = useState('scanning');
|
|
11
|
-
const [trees, setTrees] = useState([]);
|
|
12
|
-
const [error, setError] = useState(null);
|
|
13
|
-
const handleComplete = useHandle(onComplete);
|
|
14
|
-
const handleError = useHandle(onError);
|
|
15
|
-
const handleCancel = useHandle(onCancel);
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
const scan = async () => {
|
|
18
|
-
try {
|
|
19
|
-
setState('scanning');
|
|
20
|
-
const scanned = await scanPackageAssets(packageName, { local, ref });
|
|
21
|
-
setTrees(scanned);
|
|
22
|
-
setState('selecting');
|
|
23
|
-
}
|
|
24
|
-
catch (err) {
|
|
25
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
26
|
-
setError(error);
|
|
27
|
-
setState('error');
|
|
28
|
-
handleError(error);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
scan();
|
|
32
|
-
}, [packageName, local, ref, handleError]);
|
|
33
|
-
const handleSubmit = useCallback((selectedTrees) => {
|
|
34
|
-
setState('confirming');
|
|
35
|
-
const includedAssets = {};
|
|
36
|
-
const excludedAssets = {};
|
|
37
|
-
for (const tree of selectedTrees) {
|
|
38
|
-
const assetType = tree.label;
|
|
39
|
-
includedAssets[assetType] = [];
|
|
40
|
-
excludedAssets[assetType] = [];
|
|
41
|
-
if (tree.children) {
|
|
42
|
-
extractSelection(tree.children, includedAssets[assetType], excludedAssets[assetType]);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
const selection = {
|
|
46
|
-
packageName,
|
|
47
|
-
source: local ? 'local' : 'npm',
|
|
48
|
-
ref,
|
|
49
|
-
includedAssets,
|
|
50
|
-
excludedAssets,
|
|
51
|
-
};
|
|
52
|
-
setState('done');
|
|
53
|
-
handleComplete(selection);
|
|
54
|
-
}, [packageName, local, ref, handleComplete]);
|
|
55
|
-
if (state === 'scanning') {
|
|
56
|
-
return (jsx(Box, { children: jsxs(Text, { color: "cyan", children: [jsx(Spinner, { type: "dots" }), " Scanning package assets..."] }) }));
|
|
57
|
-
}
|
|
58
|
-
if (state === 'error') {
|
|
59
|
-
return (jsx(Box, { flexDirection: "column", children: jsxs(Text, { color: "red", children: ["Error: ", error?.message] }) }));
|
|
60
|
-
}
|
|
61
|
-
if (state === 'selecting') {
|
|
62
|
-
return (jsxs(Box, { flexDirection: "column", children: [jsx(Box, { marginBottom: 1, children: jsxs(Text, { bold: true, children: ["Select assets to sync from ", packageName] }) }), jsx(Box, { marginBottom: 1, children: jsx(Text, { dimColor: true, children: "Use \u2191/\u2193 to navigate, Space to toggle, \u2192/\u2190 to expand/collapse, Enter to confirm, Esc to cancel" }) }), jsx(TreeSelect, { trees: trees, onSubmit: handleSubmit, onCancel: handleCancel })] }));
|
|
63
|
-
}
|
|
64
|
-
if (state === 'confirming' || state === 'done') {
|
|
65
|
-
return (jsx(Box, { children: jsx(Text, { color: "green", children: "\u2713 Selection confirmed" }) }));
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
};
|
|
69
|
-
function extractSelection(nodes, included, excluded) {
|
|
70
|
-
for (const node of nodes) {
|
|
71
|
-
if (node.disabled)
|
|
72
|
-
continue;
|
|
73
|
-
if (node.type === 'skill-directory') {
|
|
74
|
-
if (node.selected) {
|
|
75
|
-
included.push(node.path);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
excluded.push(node.path);
|
|
79
|
-
}
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
if (node.selected) {
|
|
83
|
-
included.push(node.path);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
excluded.push(node.path);
|
|
87
|
-
}
|
|
88
|
-
if (node.children && hasPartialSelection(node)) {
|
|
89
|
-
extractSelection(node.children, included, excluded);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
function hasPartialSelection(node) {
|
|
94
|
-
if (!node.children || node.children.length === 0) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
const selectedCount = node.children.filter((c) => c.selected).length;
|
|
98
|
-
return selectedCount > 0 && selectedCount < node.children.length;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export { AddCommand };
|