@slats/claude-assets-sync 0.1.4 → 0.3.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.
Files changed (239) hide show
  1. package/README.md +89 -581
  2. package/bin/inject-claude-settings.mjs +4 -0
  3. package/dist/claude-hashes.json +20 -0
  4. package/dist/commands/index.d.ts +1 -112
  5. package/dist/commands/runCli/index.d.ts +2 -0
  6. package/dist/commands/runCli/runCli.cjs +53 -0
  7. package/dist/commands/runCli/runCli.d.ts +14 -0
  8. package/dist/commands/runCli/runCli.mjs +51 -0
  9. package/dist/commands/runCli/type.d.ts +19 -0
  10. package/dist/commands/runCli/utils/classifyTarget.cjs +48 -0
  11. package/dist/commands/runCli/utils/classifyTarget.d.ts +19 -0
  12. package/dist/commands/runCli/utils/classifyTarget.mjs +46 -0
  13. package/dist/commands/runCli/utils/injectOne.cjs +47 -0
  14. package/dist/commands/runCli/utils/injectOne.d.ts +3 -0
  15. package/dist/commands/runCli/utils/injectOne.mjs +45 -0
  16. package/dist/commands/runCli/utils/resolvePackage.cjs +77 -0
  17. package/dist/commands/runCli/utils/resolvePackage.d.ts +16 -0
  18. package/dist/commands/runCli/utils/resolvePackage.mjs +74 -0
  19. package/dist/commands/runCli/utils/resolveScopeAlias.cjs +69 -0
  20. package/dist/commands/runCli/utils/resolveScopeAlias.d.ts +2 -0
  21. package/dist/commands/runCli/utils/resolveScopeAlias.mjs +67 -0
  22. package/dist/commands/runCli/utils/resolveScopeFlag.cjs +28 -0
  23. package/dist/commands/runCli/utils/resolveScopeFlag.d.ts +2 -0
  24. package/dist/commands/runCli/utils/resolveScopeFlag.mjs +26 -0
  25. package/dist/commands/runCli/utils/resolveTargets.cjs +40 -0
  26. package/dist/commands/runCli/utils/resolveTargets.d.ts +15 -0
  27. package/dist/commands/runCli/utils/resolveTargets.mjs +38 -0
  28. package/dist/commands/runCli/utils/runInject.cjs +52 -0
  29. package/dist/commands/runCli/utils/runInject.d.ts +3 -0
  30. package/dist/commands/runCli/utils/runInject.mjs +50 -0
  31. package/dist/core/buildPlan/buildPlan.cjs +42 -0
  32. package/dist/core/buildPlan/buildPlan.d.ts +2 -0
  33. package/dist/core/buildPlan/buildPlan.mjs +40 -0
  34. package/dist/core/buildPlan/index.d.ts +2 -0
  35. package/dist/core/buildPlan/type.d.ts +32 -0
  36. package/dist/core/buildPlan/utils/toPosix.cjs +9 -0
  37. package/dist/core/buildPlan/utils/toPosix.d.ts +1 -0
  38. package/dist/core/buildPlan/utils/toPosix.mjs +7 -0
  39. package/dist/core/buildPlan/utils/walkFiles.cjs +25 -0
  40. package/dist/core/buildPlan/utils/walkFiles.d.ts +1 -0
  41. package/dist/core/buildPlan/utils/walkFiles.mjs +23 -0
  42. package/dist/core/hash/hash.cjs +30 -0
  43. package/dist/core/hash/hash.d.ts +4 -0
  44. package/dist/core/hash/hash.mjs +26 -0
  45. package/dist/core/hash/index.d.ts +1 -0
  46. package/dist/core/hashManifest/hashManifest.cjs +27 -0
  47. package/dist/core/hashManifest/hashManifest.d.ts +17 -0
  48. package/dist/core/hashManifest/hashManifest.mjs +23 -0
  49. package/dist/core/hashManifest/index.d.ts +1 -0
  50. package/dist/core/index.d.ts +5 -0
  51. package/dist/core/injectDocs/index.d.ts +2 -0
  52. package/dist/core/injectDocs/injectDocs.cjs +43 -0
  53. package/dist/core/injectDocs/injectDocs.d.ts +2 -0
  54. package/dist/core/injectDocs/injectDocs.mjs +41 -0
  55. package/dist/core/injectDocs/type.d.ts +30 -0
  56. package/dist/core/injectDocs/utils/applyAction.cjs +21 -0
  57. package/dist/core/injectDocs/utils/applyAction.d.ts +2 -0
  58. package/dist/core/injectDocs/utils/applyAction.mjs +19 -0
  59. package/dist/core/injectDocs/utils/emitCiForceList.cjs +10 -0
  60. package/dist/core/injectDocs/utils/emitCiForceList.d.ts +2 -0
  61. package/dist/core/injectDocs/utils/emitCiForceList.mjs +8 -0
  62. package/dist/core/injectDocs/utils/printPlan.cjs +20 -0
  63. package/dist/core/injectDocs/utils/printPlan.d.ts +2 -0
  64. package/dist/core/injectDocs/utils/printPlan.mjs +18 -0
  65. package/dist/core/injectDocs/utils/summarize.cjs +27 -0
  66. package/dist/core/injectDocs/utils/summarize.d.ts +3 -0
  67. package/dist/core/injectDocs/utils/summarize.mjs +25 -0
  68. package/dist/core/scope/index.d.ts +1 -0
  69. package/dist/core/scope/scope.cjs +46 -0
  70. package/dist/core/scope/scope.d.ts +16 -0
  71. package/dist/core/scope/scope.mjs +41 -0
  72. package/dist/core/scope/utils/isDirectory.cjs +14 -0
  73. package/dist/core/scope/utils/isDirectory.d.ts +1 -0
  74. package/dist/core/scope/utils/isDirectory.mjs +12 -0
  75. package/dist/index.cjs +15 -9
  76. package/dist/index.d.ts +3 -5
  77. package/dist/index.mjs +7 -3
  78. package/dist/prompts/confirmForce.cjs +27 -0
  79. package/dist/prompts/confirmForce.d.ts +1 -0
  80. package/dist/prompts/confirmForce.mjs +25 -0
  81. package/dist/prompts/index.d.ts +2 -0
  82. package/dist/prompts/selectScope.cjs +30 -0
  83. package/dist/prompts/selectScope.d.ts +2 -0
  84. package/dist/prompts/selectScope.mjs +28 -0
  85. package/dist/utils/heartbeat.cjs +25 -0
  86. package/dist/utils/heartbeat.d.ts +16 -0
  87. package/dist/utils/heartbeat.mjs +23 -0
  88. package/dist/utils/logger.cjs +7 -0
  89. package/dist/utils/logger.d.ts +8 -0
  90. package/dist/utils/logger.mjs +7 -0
  91. package/dist/utils/types.d.ts +1 -252
  92. package/dist/utils/version.cjs +2 -14
  93. package/dist/utils/version.d.ts +3 -53
  94. package/dist/utils/version.mjs +2 -13
  95. package/docs/bundle-size-decision.md +36 -0
  96. package/docs/claude/skills/claude-docs-asset-wiring/SKILL.md +159 -0
  97. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/claude-md-template.md +86 -0
  98. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/dependency-cruiser.md +54 -0
  99. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/gotchas.md +122 -0
  100. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/package-json-patches.md +145 -0
  101. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/reference-files.md +37 -0
  102. package/docs/claude/skills/claude-docs-asset-wiring/knowledge/smoke-tests.md +111 -0
  103. package/docs/consumer-integration.md +94 -0
  104. package/package.json +24 -16
  105. package/scripts/build-hashes.mjs +30 -0
  106. package/scripts/buildHashes.d.mts +15 -0
  107. package/scripts/buildHashes.mjs +82 -0
  108. package/scripts/claude-build-hashes.mjs +42 -0
  109. package/scripts/inject-version.js +112 -0
  110. package/dist/cli.cjs +0 -8
  111. package/dist/cli.d.ts +0 -1
  112. package/dist/cli.mjs +0 -7
  113. package/dist/commands/add.cjs +0 -80
  114. package/dist/commands/add.d.ts +0 -8
  115. package/dist/commands/add.mjs +0 -78
  116. package/dist/commands/list.cjs +0 -94
  117. package/dist/commands/list.d.ts +0 -15
  118. package/dist/commands/list.mjs +0 -91
  119. package/dist/commands/migrate.cjs +0 -9
  120. package/dist/commands/migrate.d.ts +0 -6
  121. package/dist/commands/migrate.mjs +0 -7
  122. package/dist/commands/remove.cjs +0 -127
  123. package/dist/commands/remove.d.ts +0 -6
  124. package/dist/commands/remove.mjs +0 -105
  125. package/dist/commands/status.cjs +0 -193
  126. package/dist/commands/status.d.ts +0 -6
  127. package/dist/commands/status.mjs +0 -171
  128. package/dist/commands/sync.cjs +0 -28
  129. package/dist/commands/sync.d.ts +0 -6
  130. package/dist/commands/sync.mjs +0 -26
  131. package/dist/commands/types.d.ts +0 -89
  132. package/dist/commands/update.cjs +0 -209
  133. package/dist/commands/update.d.ts +0 -29
  134. package/dist/commands/update.mjs +0 -206
  135. package/dist/components/add/AddCommand.cjs +0 -103
  136. package/dist/components/add/AddCommand.d.ts +0 -14
  137. package/dist/components/add/AddCommand.mjs +0 -101
  138. package/dist/components/add/BulkAddView.cjs +0 -165
  139. package/dist/components/add/BulkAddView.d.ts +0 -11
  140. package/dist/components/add/BulkAddView.mjs +0 -163
  141. package/dist/components/add/index.d.ts +0 -2
  142. package/dist/components/index.d.ts +0 -2
  143. package/dist/components/list/EditableTreeItem.d.ts +0 -13
  144. package/dist/components/list/ListCommand.cjs +0 -651
  145. package/dist/components/list/ListCommand.d.ts +0 -5
  146. package/dist/components/list/ListCommand.mjs +0 -649
  147. package/dist/components/list/SyncedPackageTree.d.ts +0 -14
  148. package/dist/components/list/index.d.ts +0 -10
  149. package/dist/components/list/types.d.ts +0 -14
  150. package/dist/components/primitives/Box.d.ts +0 -4
  151. package/dist/components/primitives/Spinner.d.ts +0 -6
  152. package/dist/components/primitives/Text.d.ts +0 -4
  153. package/dist/components/primitives/index.d.ts +0 -3
  154. package/dist/components/remove/RemoveConfirm.cjs +0 -18
  155. package/dist/components/remove/RemoveConfirm.d.ts +0 -11
  156. package/dist/components/remove/RemoveConfirm.mjs +0 -16
  157. package/dist/components/shared/Confirm.cjs +0 -30
  158. package/dist/components/shared/Confirm.d.ts +0 -8
  159. package/dist/components/shared/Confirm.mjs +0 -28
  160. package/dist/components/shared/MenuItem.cjs +0 -18
  161. package/dist/components/shared/MenuItem.d.ts +0 -7
  162. package/dist/components/shared/MenuItem.mjs +0 -16
  163. package/dist/components/shared/ProgressBar.d.ts +0 -7
  164. package/dist/components/shared/StepRunner.cjs +0 -58
  165. package/dist/components/shared/StepRunner.d.ts +0 -15
  166. package/dist/components/shared/StepRunner.mjs +0 -56
  167. package/dist/components/shared/Table.cjs +0 -19
  168. package/dist/components/shared/Table.d.ts +0 -8
  169. package/dist/components/shared/Table.mjs +0 -17
  170. package/dist/components/shared/index.d.ts +0 -6
  171. package/dist/components/status/PackageStatusCard.d.ts +0 -10
  172. package/dist/components/status/StatusDisplay.cjs +0 -26
  173. package/dist/components/status/StatusDisplay.d.ts +0 -23
  174. package/dist/components/status/StatusDisplay.mjs +0 -24
  175. package/dist/components/status/StatusTreeNode.cjs +0 -40
  176. package/dist/components/status/StatusTreeNode.d.ts +0 -15
  177. package/dist/components/status/StatusTreeNode.mjs +0 -38
  178. package/dist/components/status/index.d.ts +0 -6
  179. package/dist/components/tree/AssetTreeNode.cjs +0 -54
  180. package/dist/components/tree/AssetTreeNode.d.ts +0 -12
  181. package/dist/components/tree/AssetTreeNode.mjs +0 -52
  182. package/dist/components/tree/TreeSelect.cjs +0 -129
  183. package/dist/components/tree/TreeSelect.d.ts +0 -12
  184. package/dist/components/tree/TreeSelect.mjs +0 -127
  185. package/dist/components/tree/index.d.ts +0 -4
  186. package/dist/core/assetStructure.cjs +0 -30
  187. package/dist/core/assetStructure.d.ts +0 -36
  188. package/dist/core/assetStructure.mjs +0 -27
  189. package/dist/core/cli.cjs +0 -106
  190. package/dist/core/cli.d.ts +0 -9
  191. package/dist/core/cli.mjs +0 -103
  192. package/dist/core/constants.cjs +0 -28
  193. package/dist/core/constants.d.ts +0 -94
  194. package/dist/core/constants.mjs +0 -21
  195. package/dist/core/filesystem.cjs +0 -98
  196. package/dist/core/filesystem.d.ts +0 -94
  197. package/dist/core/filesystem.mjs +0 -88
  198. package/dist/core/github.cjs +0 -115
  199. package/dist/core/github.d.ts +0 -61
  200. package/dist/core/github.mjs +0 -107
  201. package/dist/core/io.cjs +0 -46
  202. package/dist/core/io.d.ts +0 -40
  203. package/dist/core/io.mjs +0 -39
  204. package/dist/core/listOperations.cjs +0 -228
  205. package/dist/core/listOperations.d.ts +0 -43
  206. package/dist/core/listOperations.mjs +0 -205
  207. package/dist/core/localSource.cjs +0 -126
  208. package/dist/core/localSource.d.ts +0 -33
  209. package/dist/core/localSource.mjs +0 -120
  210. package/dist/core/migration.cjs +0 -201
  211. package/dist/core/migration.d.ts +0 -57
  212. package/dist/core/migration.mjs +0 -198
  213. package/dist/core/packageScanner.cjs +0 -360
  214. package/dist/core/packageScanner.d.ts +0 -22
  215. package/dist/core/packageScanner.mjs +0 -356
  216. package/dist/core/sync.cjs +0 -400
  217. package/dist/core/sync.d.ts +0 -21
  218. package/dist/core/sync.mjs +0 -397
  219. package/dist/core/syncMeta.cjs +0 -242
  220. package/dist/core/syncMeta.d.ts +0 -75
  221. package/dist/core/syncMeta.mjs +0 -229
  222. package/dist/utils/dependencies.cjs +0 -57
  223. package/dist/utils/dependencies.d.ts +0 -10
  224. package/dist/utils/dependencies.mjs +0 -34
  225. package/dist/utils/nameTransform.cjs +0 -13
  226. package/dist/utils/nameTransform.d.ts +0 -65
  227. package/dist/utils/nameTransform.mjs +0 -11
  228. package/dist/utils/package.cjs +0 -170
  229. package/dist/utils/package.d.ts +0 -105
  230. package/dist/utils/package.mjs +0 -157
  231. package/dist/utils/packageName.cjs +0 -24
  232. package/dist/utils/packageName.d.ts +0 -32
  233. package/dist/utils/packageName.mjs +0 -21
  234. package/dist/utils/paths.cjs +0 -18
  235. package/dist/utils/paths.d.ts +0 -55
  236. package/dist/utils/paths.mjs +0 -15
  237. package/dist/version.cjs +0 -5
  238. package/dist/version.d.ts +0 -5
  239. package/dist/version.mjs +0 -3
@@ -1,651 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var ink = require('ink');
5
- var SelectInput = require('ink-select-input');
6
- var Spinner = require('ink-spinner');
7
- var React = require('react');
8
- var listOperations = require('../../core/listOperations.cjs');
9
- var packageScanner = require('../../core/packageScanner.cjs');
10
- var sync = require('../../core/sync.cjs');
11
- var syncMeta = require('../../core/syncMeta.cjs');
12
- var update = require('../../commands/update.cjs');
13
- var _package = require('../../utils/package.cjs');
14
- var Confirm = require('../shared/Confirm.cjs');
15
- var MenuItem = require('../shared/MenuItem.cjs');
16
- var StepRunner = require('../shared/StepRunner.cjs');
17
- var Table = require('../shared/Table.cjs');
18
- var TreeSelect = require('../tree/TreeSelect.cjs');
19
-
20
- function buildPackageDetail(prefix, info, syncedAt) {
21
- let totalAssets = 0;
22
- for (const files of Object.values(info.files)) {
23
- totalAssets += Array.isArray(files) ? files.length : 0;
24
- }
25
- return {
26
- prefix,
27
- originalName: info.originalName,
28
- version: info.version,
29
- local: info.local ?? false,
30
- syncedAt,
31
- files: info.files,
32
- totalAssets,
33
- };
34
- }
35
- function formatSyncDate(dateStr) {
36
- if (!dateStr)
37
- return 'unknown';
38
- try {
39
- return new Date(dateStr).toLocaleString();
40
- }
41
- catch {
42
- return dateStr;
43
- }
44
- }
45
- const ListCommand = ({ cwd }) => {
46
- const { exit } = ink.useApp();
47
- const [phase, setPhase] = React.useState('loading');
48
- const [meta, setMeta] = React.useState(null);
49
- const [errorMessage, setErrorMessage] = React.useState(null);
50
- const [selectedPackage, setSelectedPackage] = React.useState(null);
51
- const [syncSteps, setSyncSteps] = React.useState([]);
52
- const [packageFiles, setPackageFiles] = React.useState({});
53
- const [editTrees, setEditTrees] = React.useState([]);
54
- const [updateChecking, setUpdateChecking] = React.useState(false);
55
- const [updateResult, setUpdateResult] = React.useState(null);
56
- const [updateConfirmPending, setUpdateConfirmPending] = React.useState(false);
57
- const [updateSyncSteps, setUpdateSyncSteps] = React.useState([]);
58
- const [updateSyncing, setUpdateSyncing] = React.useState(false);
59
- const [checkingRemote, setCheckingRemote] = React.useState(false);
60
- const [remoteVersions, setRemoteVersions] = React.useState(null);
61
- const hasLoadedRef = React.useRef(false);
62
- ink.useInput((_input, key) => {
63
- if (!key.escape)
64
- return;
65
- switch (phase) {
66
- case 'main-menu':
67
- exit();
68
- break;
69
- case 'package-list':
70
- setPhase('main-menu');
71
- break;
72
- case 'package-detail':
73
- setSelectedPackage(null);
74
- setPhase('package-list');
75
- break;
76
- case 'edit-assets':
77
- setPhase('package-detail');
78
- break;
79
- case 'status-view':
80
- setRemoteVersions(null);
81
- setCheckingRemote(false);
82
- setPhase('main-menu');
83
- break;
84
- case 'error':
85
- exit();
86
- break;
87
- }
88
- });
89
- React.useEffect(() => {
90
- if (phase !== 'done')
91
- return;
92
- const timer = setTimeout(() => exit(), 1500);
93
- return () => clearTimeout(timer);
94
- }, [phase, exit]);
95
- const loadMeta = React.useCallback(() => {
96
- try {
97
- const loaded = syncMeta.readUnifiedSyncMeta(cwd);
98
- setMeta(loaded);
99
- return loaded;
100
- }
101
- catch (err) {
102
- setErrorMessage(err instanceof Error ? err.message : 'Failed to load sync metadata');
103
- setPhase('error');
104
- return null;
105
- }
106
- }, [cwd]);
107
- React.useEffect(() => {
108
- if (!hasLoadedRef.current) {
109
- hasLoadedRef.current = true;
110
- const loaded = loadMeta();
111
- if (loaded && Object.keys(loaded.packages).length > 0) {
112
- setPhase('main-menu');
113
- }
114
- else if (loaded) {
115
- setPhase('done');
116
- }
117
- }
118
- }, [loadMeta]);
119
- const reloadMeta = React.useCallback(() => {
120
- const loaded = loadMeta();
121
- if (loaded && selectedPackage) {
122
- const pkgInfo = loaded.packages[selectedPackage.prefix];
123
- if (pkgInfo) {
124
- setSelectedPackage(buildPackageDetail(selectedPackage.prefix, pkgInfo, loaded.syncedAt));
125
- }
126
- else {
127
- setSelectedPackage(null);
128
- }
129
- }
130
- return loaded;
131
- }, [loadMeta, selectedPackage]);
132
- const handleMainMenuSelect = (item) => {
133
- switch (item.value) {
134
- case 'packages':
135
- setPhase('package-list');
136
- break;
137
- case 'status':
138
- setRemoteVersions(null);
139
- setCheckingRemote(false);
140
- setPhase('status-view');
141
- break;
142
- case 'exit':
143
- exit();
144
- break;
145
- }
146
- };
147
- const handlePackageSelect = (item) => {
148
- if (item.value === 'back') {
149
- setPhase('main-menu');
150
- return;
151
- }
152
- if (!meta)
153
- return;
154
- const prefix = item.value;
155
- const pkgInfo = meta.packages[prefix];
156
- if (pkgInfo) {
157
- setSelectedPackage(buildPackageDetail(prefix, pkgInfo, meta.syncedAt));
158
- setPhase('package-detail');
159
- }
160
- };
161
- const handleDetailActionSelect = (item) => {
162
- switch (item.value) {
163
- case 'sync':
164
- setPhase('sync-action');
165
- handleSyncAction();
166
- break;
167
- case 'update':
168
- setUpdateResult(null);
169
- setUpdateConfirmPending(false);
170
- setUpdateSyncing(false);
171
- setUpdateSyncSteps([]);
172
- setPhase('update-action');
173
- handleUpdateActionCheck();
174
- break;
175
- case 'edit-assets':
176
- handleEditAssetsInit();
177
- break;
178
- case 'remove':
179
- setPhase('remove-action');
180
- break;
181
- case 'back':
182
- setSelectedPackage(null);
183
- setPhase('package-list');
184
- break;
185
- }
186
- };
187
- const handleSyncAction = async () => {
188
- if (!selectedPackage || !meta)
189
- return;
190
- const pkgInfo = meta.packages[selectedPackage.prefix];
191
- if (!pkgInfo)
192
- return;
193
- setSyncSteps([
194
- { name: `Syncing ${selectedPackage.originalName}`, status: 'running' },
195
- ]);
196
- try {
197
- await sync.syncPackage(selectedPackage.originalName, {
198
- force: true,
199
- dryRun: false,
200
- local: pkgInfo.local ?? false,
201
- ref: undefined,
202
- flat: undefined,
203
- }, cwd, pkgInfo.exclusions);
204
- setSyncSteps([
205
- { name: `Syncing ${selectedPackage.originalName}`, status: 'success' },
206
- ]);
207
- }
208
- catch (err) {
209
- setSyncSteps([
210
- {
211
- name: `Syncing ${selectedPackage.originalName}`,
212
- status: 'failed',
213
- error: err instanceof Error ? err.message : String(err),
214
- },
215
- ]);
216
- }
217
- setTimeout(() => {
218
- reloadMeta();
219
- setPhase('package-detail');
220
- }, 1000);
221
- };
222
- const handleUpdateActionCheck = async () => {
223
- if (!selectedPackage || !meta)
224
- return;
225
- setUpdateChecking(true);
226
- const pkgInfo = meta.packages[selectedPackage.prefix];
227
- if (!pkgInfo)
228
- return;
229
- const isLocal = pkgInfo.local ?? false;
230
- try {
231
- const currentPkgInfo = isLocal
232
- ? _package.readLocalPackageJson(pkgInfo.originalName, cwd)
233
- : _package.readPackageJson(pkgInfo.originalName, cwd);
234
- if (!currentPkgInfo) {
235
- setUpdateResult({ versionChanged: false, notFound: true });
236
- setUpdateChecking(false);
237
- setTimeout(() => {
238
- reloadMeta();
239
- setPhase('package-detail');
240
- }, 2000);
241
- return;
242
- }
243
- const installedVersion = currentPkgInfo.version;
244
- const syncedVersion = pkgInfo.version;
245
- if (installedVersion === syncedVersion) {
246
- setUpdateResult({
247
- versionChanged: false,
248
- oldVersion: syncedVersion,
249
- newVersion: installedVersion,
250
- });
251
- setUpdateChecking(false);
252
- setTimeout(() => {
253
- reloadMeta();
254
- setPhase('package-detail');
255
- }, 1500);
256
- }
257
- else {
258
- setUpdateResult({
259
- versionChanged: true,
260
- oldVersion: syncedVersion,
261
- newVersion: installedVersion,
262
- });
263
- setUpdateChecking(false);
264
- setUpdateConfirmPending(true);
265
- }
266
- }
267
- catch {
268
- setUpdateResult({ versionChanged: false, notFound: true });
269
- setUpdateChecking(false);
270
- setTimeout(() => {
271
- reloadMeta();
272
- setPhase('package-detail');
273
- }, 2000);
274
- }
275
- };
276
- const handleUpdateConfirm = async (yes) => {
277
- setUpdateConfirmPending(false);
278
- if (!yes) {
279
- reloadMeta();
280
- setPhase('package-detail');
281
- return;
282
- }
283
- if (!selectedPackage || !meta)
284
- return;
285
- setUpdateSyncing(true);
286
- setUpdateSyncSteps([
287
- { name: 'Updating version and syncing files...', status: 'running' },
288
- ]);
289
- try {
290
- await update.updatePackageVersionAndSync(selectedPackage.prefix, meta, { local: meta.packages[selectedPackage.prefix]?.local, sync: true }, cwd);
291
- setUpdateSyncSteps([
292
- { name: 'Version updated and files synced', status: 'success' },
293
- ]);
294
- }
295
- catch (err) {
296
- setUpdateSyncSteps([
297
- {
298
- name: 'Update version',
299
- status: 'failed',
300
- error: err instanceof Error ? err.message : String(err),
301
- },
302
- ]);
303
- }
304
- setTimeout(() => {
305
- reloadMeta();
306
- setPhase('package-detail');
307
- }, 1000);
308
- };
309
- const handleRemoveConfirm = async (yes) => {
310
- if (!yes) {
311
- setPhase('package-detail');
312
- return;
313
- }
314
- if (!selectedPackage || !meta)
315
- return;
316
- const pkgInfo = meta.packages[selectedPackage.prefix];
317
- if (!pkgInfo)
318
- return;
319
- try {
320
- const filesToDelete = [];
321
- const fileOperations = [];
322
- for (const [assetType, files] of Object.entries(pkgInfo.files)) {
323
- if (!Array.isArray(files))
324
- continue;
325
- const units = files;
326
- for (const unit of units) {
327
- fileOperations.push({
328
- type: 'remove',
329
- prefix: selectedPackage.prefix,
330
- assetType,
331
- skillName: unit.name,
332
- });
333
- }
334
- }
335
- await listOperations.applyChangesAndSync({ filesToDelete, fileOperations, packagesToSync: [] }, meta, cwd);
336
- const reloaded = reloadMeta();
337
- if (reloaded &&
338
- Object.keys(reloaded.packages).length > 0) {
339
- setSelectedPackage(null);
340
- setPhase('package-list');
341
- }
342
- else {
343
- setPhase('done');
344
- }
345
- }
346
- catch (err) {
347
- setErrorMessage(err instanceof Error ? err.message : 'Failed to remove package');
348
- setPhase('error');
349
- }
350
- };
351
- const handleEditAssetsInit = async () => {
352
- if (!selectedPackage || !meta)
353
- return;
354
- setPhase('edit-assets');
355
- const pkgInfo = meta.packages[selectedPackage.prefix];
356
- if (!pkgInfo)
357
- return;
358
- const prefix = selectedPackage.prefix;
359
- try {
360
- const isLocal = pkgInfo.local ?? true;
361
- let scannedTrees = await packageScanner.scanPackageAssets(pkgInfo.originalName, {
362
- local: isLocal,
363
- ref: undefined,
364
- }).catch(() => null);
365
- if (!scannedTrees && pkgInfo.local === undefined) {
366
- scannedTrees = await packageScanner.scanPackageAssets(pkgInfo.originalName, {
367
- local: !isLocal,
368
- ref: undefined,
369
- }).catch(() => null);
370
- }
371
- let available;
372
- if (scannedTrees) {
373
- available = scannedTrees;
374
- }
375
- else {
376
- available = buildFallbackTrees(prefix, pkgInfo);
377
- }
378
- const excludedFiles = new Set(pkgInfo.exclusions?.files || []);
379
- const metaSelectedFiles = new Set(Object.entries(pkgInfo.files).flatMap(([assetType, files]) => (Array.isArray(files) ? files : [])
380
- .map((unit) => {
381
- const filePath = `${assetType}/${unit.name}`;
382
- if (excludedFiles.has(filePath) ||
383
- excludedFiles.has(unit.name)) {
384
- return null;
385
- }
386
- return filePath;
387
- })
388
- .filter((f) => f !== null)));
389
- const newPackageFiles = {
390
- [prefix]: { available, selected: metaSelectedFiles },
391
- };
392
- setPackageFiles(newPackageFiles);
393
- const trees = buildEditTrees(prefix, pkgInfo, available, metaSelectedFiles);
394
- setEditTrees(trees);
395
- }
396
- catch {
397
- setPhase('package-detail');
398
- }
399
- };
400
- const handleEditAssetsSubmit = async (selectedTrees) => {
401
- if (!meta || !selectedPackage)
402
- return;
403
- const summary = listOperations.computeFileOperations(meta, packageFiles, selectedTrees, cwd);
404
- if (summary.filesToDelete.length === 0 &&
405
- summary.packagesToSync.length === 0 &&
406
- summary.fileOperations.length === 0) {
407
- setPhase('package-detail');
408
- return;
409
- }
410
- setPhase('sync-action');
411
- setSyncSteps([{ name: 'Applying changes...', status: 'running' }]);
412
- try {
413
- await listOperations.applyChangesAndSync(summary, meta, cwd, {
414
- onSyncStart: () => {
415
- setSyncSteps([{ name: 'Syncing files...', status: 'running' }]);
416
- },
417
- });
418
- setSyncSteps([{ name: 'Changes applied', status: 'success' }]);
419
- }
420
- catch (err) {
421
- setSyncSteps([
422
- {
423
- name: 'Apply changes',
424
- status: 'failed',
425
- error: err instanceof Error ? err.message : String(err),
426
- },
427
- ]);
428
- }
429
- setTimeout(() => {
430
- reloadMeta();
431
- setPhase('package-detail');
432
- }, 1000);
433
- };
434
- const handleEditAssetsCancel = () => {
435
- setPhase('package-detail');
436
- };
437
- const handleStatusMenuSelect = (item) => {
438
- if (item.value === 'check-remote') {
439
- handleCheckRemoteVersions();
440
- }
441
- else if (item.value === 'back') {
442
- setRemoteVersions(null);
443
- setCheckingRemote(false);
444
- setPhase('main-menu');
445
- }
446
- };
447
- const handleCheckRemoteVersions = async () => {
448
- if (!meta)
449
- return;
450
- setCheckingRemote(true);
451
- try {
452
- const versions = {};
453
- for (const [, pkgInfo] of Object.entries(meta.packages)) {
454
- try {
455
- const res = await fetch(`https://registry.npmjs.org/${pkgInfo.originalName}/latest`);
456
- if (res.ok) {
457
- const data = (await res.json());
458
- versions[pkgInfo.originalName] = data.version;
459
- }
460
- }
461
- catch {
462
- }
463
- }
464
- setRemoteVersions(versions);
465
- }
466
- catch {
467
- }
468
- finally {
469
- setCheckingRemote(false);
470
- }
471
- };
472
- if (phase === 'loading') {
473
- return (jsxRuntime.jsx(ink.Box, { children: jsxRuntime.jsxs(ink.Text, { color: "cyan", children: [jsxRuntime.jsx(Spinner, { type: "dots" }), " Loading synced packages..."] }) }));
474
- }
475
- if (phase === 'error') {
476
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsxs(ink.Text, { color: "red", children: ["Error: ", errorMessage ?? 'Unknown error'] }), jsxRuntime.jsx(ink.Box, { marginTop: 1, children: jsxRuntime.jsxs(ink.Text, { dimColor: true, children: ["Press ", jsxRuntime.jsx(ink.Text, { bold: true, children: "ESC" }), " to exit"] }) })] }));
477
- }
478
- if (phase === 'done') {
479
- if (!meta || Object.keys(meta.packages).length === 0) {
480
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Text, { color: "yellow", children: "No packages synced yet." }), jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Exiting..." })] }));
481
- }
482
- return null;
483
- }
484
- if (phase === 'main-menu' && meta) {
485
- const packageCount = Object.keys(meta.packages).length;
486
- const menuItems = [
487
- { label: `Packages (${packageCount})`, value: 'packages' },
488
- { label: 'Status', value: 'status' },
489
- { label: 'Exit', value: 'exit' },
490
- ];
491
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(SelectInput, { items: menuItems, onSelect: handleMainMenuSelect, itemComponent: MenuItem.MenuItem }), jsxRuntime.jsx(ink.Box, { marginTop: 1, children: jsxRuntime.jsxs(ink.Text, { dimColor: true, children: ["Press ", jsxRuntime.jsx(ink.Text, { bold: true, children: "ESC" }), " to exit"] }) })] }));
492
- }
493
- if (phase === 'package-list' && meta) {
494
- const items = Object.entries(meta.packages).map(([prefix, pkgInfo]) => {
495
- let totalAssets = 0;
496
- for (const files of Object.values(pkgInfo.files)) {
497
- totalAssets += Array.isArray(files) ? files.length : 0;
498
- }
499
- const syncDate = formatSyncDate(meta.syncedAt);
500
- return {
501
- label: `${pkgInfo.originalName}@${pkgInfo.version} \u2022 ${totalAssets} assets \u2022 ${syncDate}`,
502
- value: prefix,
503
- };
504
- });
505
- items.push({ label: '\u2190 Back', value: 'back' });
506
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsx(ink.Text, { bold: true, children: "Synced Packages" }) }), jsxRuntime.jsx(SelectInput, { items: items, onSelect: handlePackageSelect, itemComponent: MenuItem.MenuItem }), jsxRuntime.jsx(ink.Box, { marginTop: 1, children: jsxRuntime.jsxs(ink.Text, { dimColor: true, children: ["Press ", jsxRuntime.jsx(ink.Text, { bold: true, children: "ESC" }), " to go back"] }) })] }));
507
- }
508
- if (phase === 'package-detail' && selectedPackage && meta) {
509
- const assetEntries = Object.entries(selectedPackage.files);
510
- const actionItems = [
511
- { label: 'Sync', value: 'sync' },
512
- { label: 'Update Version', value: 'update' },
513
- { label: 'Edit Assets', value: 'edit-assets' },
514
- { label: 'Remove', value: 'remove' },
515
- { label: '\u2190 Back', value: 'back' },
516
- ];
517
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsxs(ink.Text, { bold: true, children: [selectedPackage.originalName, "@", selectedPackage.version] }) }), jsxRuntime.jsxs(ink.Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [jsxRuntime.jsxs(ink.Text, { children: [jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Source: " }), jsxRuntime.jsx(ink.Text, { children: selectedPackage.local ? 'local' : 'remote' })] }), jsxRuntime.jsxs(ink.Text, { children: [jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Synced: " }), jsxRuntime.jsx(ink.Text, { children: formatSyncDate(selectedPackage.syncedAt) })] }), jsxRuntime.jsxs(ink.Text, { children: [jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Total: " }), jsxRuntime.jsxs(ink.Text, { children: [selectedPackage.totalAssets, " assets"] })] }), assetEntries.map(([assetType, files]) => {
518
- const count = Array.isArray(files) ? files.length : 0;
519
- return (jsxRuntime.jsxs(ink.Text, { children: [jsxRuntime.jsxs(ink.Text, { dimColor: true, children: [" ", assetType, ": "] }), jsxRuntime.jsxs(ink.Text, { children: [count, " files"] })] }, assetType));
520
- })] }), jsxRuntime.jsx(SelectInput, { items: actionItems, onSelect: handleDetailActionSelect, itemComponent: MenuItem.MenuItem }), jsxRuntime.jsx(ink.Box, { marginTop: 1, children: jsxRuntime.jsxs(ink.Text, { dimColor: true, children: ["Press ", jsxRuntime.jsx(ink.Text, { bold: true, children: "ESC" }), " to go back"] }) })] }));
521
- }
522
- if (phase === 'sync-action') {
523
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsx(ink.Text, { bold: true, children: "Syncing Package" }) }), jsxRuntime.jsx(StepRunner.StepRunner, { steps: syncSteps, currentStep: 0, total: syncSteps.length })] }));
524
- }
525
- if (phase === 'remove-action' && selectedPackage) {
526
- return (jsxRuntime.jsx(ink.Box, { flexDirection: "column", children: jsxRuntime.jsx(Confirm.Confirm, { message: `Remove ${selectedPackage.originalName}? This will delete all synced files.`, onConfirm: handleRemoveConfirm, defaultYes: false }) }));
527
- }
528
- if (phase === 'update-action') {
529
- if (updateChecking) {
530
- return (jsxRuntime.jsx(ink.Box, { children: jsxRuntime.jsxs(ink.Text, { color: "cyan", children: [jsxRuntime.jsx(Spinner, { type: "dots" }), " Checking installed version..."] }) }));
531
- }
532
- if (updateSyncing) {
533
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsx(ink.Text, { bold: true, children: "Updating Package" }) }), jsxRuntime.jsx(StepRunner.StepRunner, { steps: updateSyncSteps, currentStep: 0, total: updateSyncSteps.length })] }));
534
- }
535
- if (updateConfirmPending && updateResult) {
536
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsxs(ink.Text, { children: [jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Current sync: " }), jsxRuntime.jsx(ink.Text, { color: "yellow", children: updateResult.oldVersion }), jsxRuntime.jsx(ink.Text, { dimColor: true, children: " \u2192 Installed: " }), jsxRuntime.jsx(ink.Text, { color: "green", children: updateResult.newVersion })] }) }), jsxRuntime.jsx(Confirm.Confirm, { message: "Update version and re-sync?", onConfirm: handleUpdateConfirm, defaultYes: true })] }));
537
- }
538
- if (updateResult && !updateResult.versionChanged) {
539
- if (updateResult.notFound) {
540
- return (jsxRuntime.jsx(ink.Box, { children: jsxRuntime.jsx(ink.Text, { color: "yellow", children: "Package not found in node_modules or workspace" }) }));
541
- }
542
- return (jsxRuntime.jsx(ink.Box, { children: jsxRuntime.jsxs(ink.Text, { color: "green", children: ["Already up to date (version ", updateResult.oldVersion, ")"] }) }));
543
- }
544
- return null;
545
- }
546
- if (phase === 'edit-assets') {
547
- if (editTrees.length === 0) {
548
- return (jsxRuntime.jsx(ink.Box, { children: jsxRuntime.jsxs(ink.Text, { color: "cyan", children: [jsxRuntime.jsx(Spinner, { type: "dots" }), " Loading available assets..."] }) }));
549
- }
550
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsx(ink.Text, { bold: true, children: "Edit Assets" }) }), jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsx(ink.Text, { dimColor: true, children: "Space: toggle | Enter: save | Esc: cancel" }) }), jsxRuntime.jsx(TreeSelect.TreeSelect, { trees: editTrees, onSubmit: handleEditAssetsSubmit, onCancel: handleEditAssetsCancel })] }));
551
- }
552
- if (phase === 'status-view' && meta) {
553
- const packageEntries = Object.entries(meta.packages);
554
- const statusRows = packageEntries.map(([, pkgInfo]) => {
555
- let totalAssets = 0;
556
- for (const files of Object.values(pkgInfo.files)) {
557
- totalAssets += Array.isArray(files) ? files.length : 0;
558
- }
559
- const remoteVer = remoteVersions?.[pkgInfo.originalName] ?? '-';
560
- return [
561
- pkgInfo.originalName,
562
- pkgInfo.version,
563
- remoteVer,
564
- String(totalAssets),
565
- formatSyncDate(meta.syncedAt),
566
- ];
567
- });
568
- const statusMenuItems = [
569
- { label: 'Check Remote Versions', value: 'check-remote' },
570
- { label: '\u2190 Back', value: 'back' },
571
- ];
572
- return (jsxRuntime.jsxs(ink.Box, { flexDirection: "column", children: [jsxRuntime.jsx(ink.Box, { marginBottom: 1, children: jsxRuntime.jsx(ink.Text, { bold: true, children: "Sync Status" }) }), jsxRuntime.jsx(Table.Table, { headers: ['Package', 'Local', 'Remote', 'Assets', 'Synced'], rows: statusRows }), checkingRemote && (jsxRuntime.jsx(ink.Box, { marginTop: 1, children: jsxRuntime.jsxs(ink.Text, { color: "cyan", children: [jsxRuntime.jsx(Spinner, { type: "dots" }), " Checking remote versions..."] }) })), jsxRuntime.jsx(ink.Box, { marginTop: 1, children: jsxRuntime.jsx(SelectInput, { items: statusMenuItems, onSelect: handleStatusMenuSelect, itemComponent: MenuItem.MenuItem }) }), jsxRuntime.jsx(ink.Box, { marginTop: 1, children: jsxRuntime.jsxs(ink.Text, { dimColor: true, children: ["Press ", jsxRuntime.jsx(ink.Text, { bold: true, children: "ESC" }), " to go back"] }) })] }));
573
- }
574
- return null;
575
- };
576
- function buildFallbackTrees(prefix, packageInfo) {
577
- const assetTypeTrees = [];
578
- for (const [assetType, files] of Object.entries(packageInfo.files)) {
579
- const units = Array.isArray(files) ? files : [];
580
- if (units.length === 0)
581
- continue;
582
- const skillNodes = units.map((unit) => {
583
- const displayName = unit.transformed ?? unit.name;
584
- if (unit.isDirectory) {
585
- return {
586
- id: `${prefix}/${assetType}/${displayName}`,
587
- label: displayName,
588
- path: `${assetType}/${unit.name}`,
589
- type: 'skill-directory',
590
- viewOnly: true,
591
- selected: true,
592
- expanded: false,
593
- children: (unit.internalFiles || []).map((f) => ({
594
- id: `${prefix}/${assetType}/${displayName}/${f}`,
595
- label: f,
596
- path: `${assetType}/${unit.name}/${f}`,
597
- type: 'file',
598
- selected: true,
599
- expanded: false,
600
- disabled: true,
601
- })),
602
- };
603
- }
604
- return {
605
- id: `${prefix}/${assetType}/${displayName}`,
606
- label: displayName,
607
- path: `${assetType}/${unit.name}`,
608
- type: 'file',
609
- selected: true,
610
- expanded: false,
611
- };
612
- });
613
- assetTypeTrees.push({
614
- id: `${prefix}/${assetType}`,
615
- label: assetType,
616
- path: assetType,
617
- type: 'directory',
618
- children: skillNodes,
619
- selected: true,
620
- expanded: true,
621
- });
622
- }
623
- return assetTypeTrees;
624
- }
625
- function buildEditTrees(prefix, packageInfo, available, selectedFiles) {
626
- const assetTypeTrees = available.map((assetTypeTree) => {
627
- const clonedTree = { ...assetTypeTree };
628
- if (clonedTree.children) {
629
- clonedTree.children = clonedTree.children.map((fileNode) => {
630
- const selected = selectedFiles.has(fileNode.path);
631
- return { ...fileNode, selected };
632
- });
633
- const anySelected = clonedTree.children.some((f) => f.selected);
634
- clonedTree.selected = anySelected;
635
- }
636
- return clonedTree;
637
- });
638
- return [
639
- {
640
- id: prefix,
641
- label: `${packageInfo.originalName}@${packageInfo.version}`,
642
- path: packageInfo.originalName,
643
- type: 'directory',
644
- children: assetTypeTrees,
645
- selected: true,
646
- expanded: true,
647
- },
648
- ];
649
- }
650
-
651
- exports.ListCommand = ListCommand;
@@ -1,5 +0,0 @@
1
- import React from 'react';
2
- export interface ListCommandProps {
3
- cwd: string;
4
- }
5
- export declare const ListCommand: React.FC<ListCommandProps>;