@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.
Files changed (227) hide show
  1. package/README.md +111 -587
  2. package/bin/claude-sync.mjs +24 -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 +31 -0
  7. package/dist/commands/runCli/runCli.d.ts +10 -0
  8. package/dist/commands/runCli/runCli.mjs +29 -0
  9. package/dist/commands/runCli/type.d.ts +28 -0
  10. package/dist/commands/runCli/utils/injectOne.cjs +48 -0
  11. package/dist/commands/runCli/utils/injectOne.d.ts +3 -0
  12. package/dist/commands/runCli/utils/injectOne.mjs +46 -0
  13. package/dist/commands/runCli/utils/resolveScopeFlag.cjs +28 -0
  14. package/dist/commands/runCli/utils/resolveScopeFlag.d.ts +2 -0
  15. package/dist/commands/runCli/utils/resolveScopeFlag.mjs +26 -0
  16. package/dist/commands/runCli/utils/runInject.cjs +36 -0
  17. package/dist/commands/runCli/utils/runInject.d.ts +2 -0
  18. package/dist/commands/runCli/utils/runInject.mjs +34 -0
  19. package/dist/core/buildPlan/buildPlan.cjs +42 -0
  20. package/dist/core/buildPlan/buildPlan.d.ts +2 -0
  21. package/dist/core/buildPlan/buildPlan.mjs +40 -0
  22. package/dist/core/buildPlan/index.d.ts +2 -0
  23. package/dist/core/buildPlan/type.d.ts +32 -0
  24. package/dist/core/buildPlan/utils/toPosix.cjs +9 -0
  25. package/dist/core/buildPlan/utils/toPosix.d.ts +1 -0
  26. package/dist/core/buildPlan/utils/toPosix.mjs +7 -0
  27. package/dist/core/buildPlan/utils/walkFiles.cjs +25 -0
  28. package/dist/core/buildPlan/utils/walkFiles.d.ts +1 -0
  29. package/dist/core/buildPlan/utils/walkFiles.mjs +23 -0
  30. package/dist/core/hash/hash.cjs +30 -0
  31. package/dist/core/hash/hash.d.ts +4 -0
  32. package/dist/core/hash/hash.mjs +26 -0
  33. package/dist/core/hash/index.d.ts +1 -0
  34. package/dist/core/hashManifest/hashManifest.cjs +27 -0
  35. package/dist/core/hashManifest/hashManifest.d.ts +17 -0
  36. package/dist/core/hashManifest/hashManifest.mjs +23 -0
  37. package/dist/core/hashManifest/index.d.ts +1 -0
  38. package/dist/core/index.d.ts +5 -0
  39. package/dist/core/injectDocs/index.d.ts +2 -0
  40. package/dist/core/injectDocs/injectDocs.cjs +43 -0
  41. package/dist/core/injectDocs/injectDocs.d.ts +2 -0
  42. package/dist/core/injectDocs/injectDocs.mjs +41 -0
  43. package/dist/core/injectDocs/type.d.ts +30 -0
  44. package/dist/core/injectDocs/utils/applyAction.cjs +21 -0
  45. package/dist/core/injectDocs/utils/applyAction.d.ts +2 -0
  46. package/dist/core/injectDocs/utils/applyAction.mjs +19 -0
  47. package/dist/core/injectDocs/utils/emitCiForceList.cjs +10 -0
  48. package/dist/core/injectDocs/utils/emitCiForceList.d.ts +2 -0
  49. package/dist/core/injectDocs/utils/emitCiForceList.mjs +8 -0
  50. package/dist/core/injectDocs/utils/printPlan.cjs +20 -0
  51. package/dist/core/injectDocs/utils/printPlan.d.ts +2 -0
  52. package/dist/core/injectDocs/utils/printPlan.mjs +18 -0
  53. package/dist/core/injectDocs/utils/summarize.cjs +27 -0
  54. package/dist/core/injectDocs/utils/summarize.d.ts +3 -0
  55. package/dist/core/injectDocs/utils/summarize.mjs +25 -0
  56. package/dist/core/scope/index.d.ts +1 -0
  57. package/dist/core/scope/scope.cjs +46 -0
  58. package/dist/core/scope/scope.d.ts +16 -0
  59. package/dist/core/scope/scope.mjs +41 -0
  60. package/dist/core/scope/utils/isDirectory.cjs +14 -0
  61. package/dist/core/scope/utils/isDirectory.d.ts +1 -0
  62. package/dist/core/scope/utils/isDirectory.mjs +12 -0
  63. package/dist/index.cjs +15 -9
  64. package/dist/index.d.ts +3 -5
  65. package/dist/index.mjs +7 -3
  66. package/dist/prompts/confirmForce.cjs +27 -0
  67. package/dist/prompts/confirmForce.d.ts +1 -0
  68. package/dist/prompts/confirmForce.mjs +25 -0
  69. package/dist/prompts/index.d.ts +2 -0
  70. package/dist/prompts/selectScope.cjs +30 -0
  71. package/dist/prompts/selectScope.d.ts +2 -0
  72. package/dist/prompts/selectScope.mjs +28 -0
  73. package/dist/utils/heartbeat.cjs +25 -0
  74. package/dist/utils/heartbeat.d.ts +16 -0
  75. package/dist/utils/heartbeat.mjs +23 -0
  76. package/dist/utils/logger.cjs +7 -0
  77. package/dist/utils/logger.d.ts +8 -0
  78. package/dist/utils/logger.mjs +7 -0
  79. package/dist/utils/types.d.ts +1 -252
  80. package/dist/utils/version.cjs +2 -14
  81. package/dist/utils/version.d.ts +3 -53
  82. package/dist/utils/version.mjs +2 -13
  83. package/docs/bundle-size-decision.md +36 -0
  84. package/docs/claude/skills/claude-sync-applier/SKILL.md +195 -0
  85. package/docs/claude/skills/claude-sync-applier/knowledge/claude-md-template.md +77 -0
  86. package/docs/claude/skills/claude-sync-applier/knowledge/dependency-cruiser.md +126 -0
  87. package/docs/claude/skills/claude-sync-applier/knowledge/gotchas.md +139 -0
  88. package/docs/claude/skills/claude-sync-applier/knowledge/package-json-patches.md +130 -0
  89. package/docs/claude/skills/claude-sync-applier/knowledge/reference-files.md +120 -0
  90. package/docs/claude/skills/claude-sync-applier/knowledge/smoke-tests.md +102 -0
  91. package/docs/consumer-integration.md +153 -0
  92. package/package.json +24 -16
  93. package/scripts/build-hashes.mjs +30 -0
  94. package/scripts/buildHashes.d.mts +15 -0
  95. package/scripts/buildHashes.mjs +82 -0
  96. package/scripts/claude-build-hashes.mjs +42 -0
  97. package/scripts/inject-version.js +112 -0
  98. package/dist/cli.cjs +0 -8
  99. package/dist/cli.d.ts +0 -1
  100. package/dist/cli.mjs +0 -7
  101. package/dist/commands/add.cjs +0 -80
  102. package/dist/commands/add.d.ts +0 -8
  103. package/dist/commands/add.mjs +0 -78
  104. package/dist/commands/list.cjs +0 -94
  105. package/dist/commands/list.d.ts +0 -15
  106. package/dist/commands/list.mjs +0 -91
  107. package/dist/commands/migrate.cjs +0 -9
  108. package/dist/commands/migrate.d.ts +0 -6
  109. package/dist/commands/migrate.mjs +0 -7
  110. package/dist/commands/remove.cjs +0 -127
  111. package/dist/commands/remove.d.ts +0 -6
  112. package/dist/commands/remove.mjs +0 -105
  113. package/dist/commands/status.cjs +0 -193
  114. package/dist/commands/status.d.ts +0 -6
  115. package/dist/commands/status.mjs +0 -171
  116. package/dist/commands/sync.cjs +0 -28
  117. package/dist/commands/sync.d.ts +0 -6
  118. package/dist/commands/sync.mjs +0 -26
  119. package/dist/commands/types.d.ts +0 -89
  120. package/dist/commands/update.cjs +0 -209
  121. package/dist/commands/update.d.ts +0 -29
  122. package/dist/commands/update.mjs +0 -206
  123. package/dist/components/add/AddCommand.cjs +0 -103
  124. package/dist/components/add/AddCommand.d.ts +0 -14
  125. package/dist/components/add/AddCommand.mjs +0 -101
  126. package/dist/components/add/BulkAddView.cjs +0 -165
  127. package/dist/components/add/BulkAddView.d.ts +0 -11
  128. package/dist/components/add/BulkAddView.mjs +0 -163
  129. package/dist/components/add/index.d.ts +0 -2
  130. package/dist/components/index.d.ts +0 -2
  131. package/dist/components/list/EditableTreeItem.d.ts +0 -13
  132. package/dist/components/list/ListCommand.cjs +0 -651
  133. package/dist/components/list/ListCommand.d.ts +0 -5
  134. package/dist/components/list/ListCommand.mjs +0 -649
  135. package/dist/components/list/SyncedPackageTree.d.ts +0 -14
  136. package/dist/components/list/index.d.ts +0 -10
  137. package/dist/components/list/types.d.ts +0 -14
  138. package/dist/components/primitives/Box.d.ts +0 -4
  139. package/dist/components/primitives/Spinner.d.ts +0 -6
  140. package/dist/components/primitives/Text.d.ts +0 -4
  141. package/dist/components/primitives/index.d.ts +0 -3
  142. package/dist/components/remove/RemoveConfirm.cjs +0 -18
  143. package/dist/components/remove/RemoveConfirm.d.ts +0 -11
  144. package/dist/components/remove/RemoveConfirm.mjs +0 -16
  145. package/dist/components/shared/Confirm.cjs +0 -30
  146. package/dist/components/shared/Confirm.d.ts +0 -8
  147. package/dist/components/shared/Confirm.mjs +0 -28
  148. package/dist/components/shared/MenuItem.cjs +0 -18
  149. package/dist/components/shared/MenuItem.d.ts +0 -7
  150. package/dist/components/shared/MenuItem.mjs +0 -16
  151. package/dist/components/shared/ProgressBar.d.ts +0 -7
  152. package/dist/components/shared/StepRunner.cjs +0 -58
  153. package/dist/components/shared/StepRunner.d.ts +0 -15
  154. package/dist/components/shared/StepRunner.mjs +0 -56
  155. package/dist/components/shared/Table.cjs +0 -19
  156. package/dist/components/shared/Table.d.ts +0 -8
  157. package/dist/components/shared/Table.mjs +0 -17
  158. package/dist/components/shared/index.d.ts +0 -6
  159. package/dist/components/status/PackageStatusCard.d.ts +0 -10
  160. package/dist/components/status/StatusDisplay.cjs +0 -26
  161. package/dist/components/status/StatusDisplay.d.ts +0 -23
  162. package/dist/components/status/StatusDisplay.mjs +0 -24
  163. package/dist/components/status/StatusTreeNode.cjs +0 -40
  164. package/dist/components/status/StatusTreeNode.d.ts +0 -15
  165. package/dist/components/status/StatusTreeNode.mjs +0 -38
  166. package/dist/components/status/index.d.ts +0 -6
  167. package/dist/components/tree/AssetTreeNode.cjs +0 -54
  168. package/dist/components/tree/AssetTreeNode.d.ts +0 -12
  169. package/dist/components/tree/AssetTreeNode.mjs +0 -52
  170. package/dist/components/tree/TreeSelect.cjs +0 -129
  171. package/dist/components/tree/TreeSelect.d.ts +0 -12
  172. package/dist/components/tree/TreeSelect.mjs +0 -127
  173. package/dist/components/tree/index.d.ts +0 -4
  174. package/dist/core/assetStructure.cjs +0 -30
  175. package/dist/core/assetStructure.d.ts +0 -36
  176. package/dist/core/assetStructure.mjs +0 -27
  177. package/dist/core/cli.cjs +0 -106
  178. package/dist/core/cli.d.ts +0 -9
  179. package/dist/core/cli.mjs +0 -103
  180. package/dist/core/constants.cjs +0 -28
  181. package/dist/core/constants.d.ts +0 -94
  182. package/dist/core/constants.mjs +0 -21
  183. package/dist/core/filesystem.cjs +0 -98
  184. package/dist/core/filesystem.d.ts +0 -94
  185. package/dist/core/filesystem.mjs +0 -88
  186. package/dist/core/github.cjs +0 -115
  187. package/dist/core/github.d.ts +0 -61
  188. package/dist/core/github.mjs +0 -107
  189. package/dist/core/io.cjs +0 -46
  190. package/dist/core/io.d.ts +0 -40
  191. package/dist/core/io.mjs +0 -39
  192. package/dist/core/listOperations.cjs +0 -228
  193. package/dist/core/listOperations.d.ts +0 -43
  194. package/dist/core/listOperations.mjs +0 -205
  195. package/dist/core/localSource.cjs +0 -126
  196. package/dist/core/localSource.d.ts +0 -33
  197. package/dist/core/localSource.mjs +0 -120
  198. package/dist/core/migration.cjs +0 -201
  199. package/dist/core/migration.d.ts +0 -57
  200. package/dist/core/migration.mjs +0 -198
  201. package/dist/core/packageScanner.cjs +0 -360
  202. package/dist/core/packageScanner.d.ts +0 -22
  203. package/dist/core/packageScanner.mjs +0 -356
  204. package/dist/core/sync.cjs +0 -400
  205. package/dist/core/sync.d.ts +0 -21
  206. package/dist/core/sync.mjs +0 -397
  207. package/dist/core/syncMeta.cjs +0 -242
  208. package/dist/core/syncMeta.d.ts +0 -75
  209. package/dist/core/syncMeta.mjs +0 -229
  210. package/dist/utils/dependencies.cjs +0 -57
  211. package/dist/utils/dependencies.d.ts +0 -10
  212. package/dist/utils/dependencies.mjs +0 -34
  213. package/dist/utils/nameTransform.cjs +0 -13
  214. package/dist/utils/nameTransform.d.ts +0 -65
  215. package/dist/utils/nameTransform.mjs +0 -11
  216. package/dist/utils/package.cjs +0 -170
  217. package/dist/utils/package.d.ts +0 -105
  218. package/dist/utils/package.mjs +0 -157
  219. package/dist/utils/packageName.cjs +0 -24
  220. package/dist/utils/packageName.d.ts +0 -32
  221. package/dist/utils/packageName.mjs +0 -21
  222. package/dist/utils/paths.cjs +0 -18
  223. package/dist/utils/paths.d.ts +0 -55
  224. package/dist/utils/paths.mjs +0 -15
  225. package/dist/version.cjs +0 -5
  226. package/dist/version.d.ts +0 -5
  227. package/dist/version.mjs +0 -3
@@ -1,105 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import { render } from 'ink';
4
- import pc from 'picocolors';
5
- import React from 'react';
6
- import { RemoveConfirm } from '../components/remove/RemoveConfirm.mjs';
7
- import { readUnifiedSyncMeta, writeUnifiedSyncMeta } from '../core/syncMeta.mjs';
8
- import { logger } from '../utils/logger.mjs';
9
- import { packageNameToPrefix } from '../utils/packageName.mjs';
10
-
11
- function isTTY() {
12
- return process.stdout.isTTY === true && process.stdin.isTTY === true;
13
- }
14
- function performRemoval(filesToRemove, meta, prefix, packageName, cwd) {
15
- for (const { path: filePath } of filesToRemove) {
16
- try {
17
- const stat = fs.statSync(filePath);
18
- if (stat.isDirectory()) {
19
- fs.rmSync(filePath, { recursive: true, force: true });
20
- console.log(`${pc.red('-')} ${filePath}`);
21
- }
22
- else {
23
- fs.unlinkSync(filePath);
24
- console.log(`${pc.red('-')} ${filePath}`);
25
- }
26
- }
27
- catch (error) {
28
- if (error.code !== 'ENOENT') {
29
- logger.error(`Failed to remove ${filePath}: ${error}`);
30
- }
31
- }
32
- }
33
- if (meta) {
34
- delete meta.packages[prefix];
35
- meta.syncedAt = new Date().toISOString();
36
- writeUnifiedSyncMeta(cwd, meta);
37
- }
38
- logger.success(`\nRemoved package ${packageName}`);
39
- }
40
- const runRemoveCommand = async (options, cwd = process.cwd()) => {
41
- const { package: packageName, yes, dryRun } = options;
42
- const prefix = packageNameToPrefix(packageName);
43
- const meta = readUnifiedSyncMeta(cwd);
44
- if (!meta || !meta.packages || !meta.packages[prefix]) {
45
- logger.error(`Package ${packageName} is not synced.`);
46
- process.exit(1);
47
- return;
48
- }
49
- const packageInfo = meta.packages[prefix];
50
- if (!packageInfo || !packageInfo.files) {
51
- logger.error(`Package ${packageName} has no files to remove.`);
52
- process.exit(1);
53
- return;
54
- }
55
- const filesToRemove = [];
56
- for (const [assetType, files] of Object.entries(packageInfo.files)) {
57
- if (!Array.isArray(files) || files.length === 0)
58
- continue;
59
- const units = files;
60
- const firstUnit = units[0];
61
- if (firstUnit.transformed) {
62
- for (const unit of units) {
63
- const targetPath = path.join(cwd, '.claude', assetType, unit.transformed);
64
- filesToRemove.push({ assetType, path: targetPath });
65
- }
66
- }
67
- else {
68
- const dirPath = path.join(cwd, '.claude', assetType, packageName);
69
- filesToRemove.push({ assetType, path: dirPath });
70
- }
71
- }
72
- console.log(pc.bold('\nFiles to remove:\n'));
73
- for (const { assetType, path: filePath } of filesToRemove) {
74
- console.log(` ${pc.red('-')} ${assetType}: ${filePath}`);
75
- }
76
- console.log('');
77
- if (dryRun) {
78
- logger.info('[DRY RUN] No changes made.');
79
- return;
80
- }
81
- if (!yes) {
82
- if (isTTY()) {
83
- let confirmed = false;
84
- const { waitUntilExit } = render(React.createElement(RemoveConfirm, {
85
- packageName,
86
- filesToRemove,
87
- onConfirm: (result) => {
88
- confirmed = result;
89
- },
90
- }));
91
- await waitUntilExit();
92
- if (!confirmed) {
93
- logger.info('Cancelled.');
94
- return;
95
- }
96
- }
97
- else {
98
- logger.info('Cancelled (non-interactive terminal).');
99
- return;
100
- }
101
- }
102
- performRemoval(filesToRemove, meta, prefix, packageName, cwd);
103
- };
104
-
105
- export { runRemoveCommand };
@@ -1,193 +0,0 @@
1
- 'use strict';
2
-
3
- var fs = require('node:fs');
4
- var path = require('node:path');
5
- var ink = require('ink');
6
- var pc = require('picocolors');
7
- var React = require('react');
8
- var StatusDisplay = require('../components/status/StatusDisplay.cjs');
9
- require('react/jsx-runtime');
10
- var syncMeta = require('../core/syncMeta.cjs');
11
- var logger = require('../utils/logger.cjs');
12
- var _package = require('../utils/package.cjs');
13
-
14
- function _interopNamespaceDefault(e) {
15
- var n = Object.create(null);
16
- if (e) {
17
- Object.keys(e).forEach(function (k) {
18
- if (k !== 'default') {
19
- var d = Object.getOwnPropertyDescriptor(e, k);
20
- Object.defineProperty(n, k, d.get ? d : {
21
- enumerable: true,
22
- get: function () { return e[k]; }
23
- });
24
- }
25
- });
26
- }
27
- n.default = e;
28
- return Object.freeze(n);
29
- }
30
-
31
- var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
32
- var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
33
-
34
- const CACHE_DURATION = 5 * 60 * 1000;
35
- const CACHE_FILE = '.sync-version-cache.json';
36
- const fetchRemoteVersion = async (packageName) => {
37
- try {
38
- const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
39
- signal: AbortSignal.timeout(5000),
40
- });
41
- if (!response.ok) {
42
- if (response.status === 404) {
43
- return undefined;
44
- }
45
- throw new Error(`HTTP ${response.status}`);
46
- }
47
- const data = await response.json();
48
- return data.version;
49
- }
50
- catch {
51
- return undefined;
52
- }
53
- };
54
- const readVersionCache = (cwd) => {
55
- try {
56
- const cachePath = path__namespace.join(cwd, '.claude', CACHE_FILE);
57
- const content = fs__namespace.readFileSync(cachePath, 'utf-8');
58
- return JSON.parse(content);
59
- }
60
- catch {
61
- return {};
62
- }
63
- };
64
- const writeVersionCache = (cwd, cache) => {
65
- try {
66
- const cachePath = path__namespace.join(cwd, '.claude', CACHE_FILE);
67
- fs__namespace.writeFileSync(cachePath, JSON.stringify(cache, null, 2));
68
- }
69
- catch {
70
- }
71
- };
72
- const getCachedRemoteVersion = async (packageName, cwd) => {
73
- const cache = readVersionCache(cwd);
74
- const now = Date.now();
75
- const cached = cache[packageName];
76
- if (cached && now - cached.timestamp < CACHE_DURATION) {
77
- return cached.version;
78
- }
79
- const version = await fetchRemoteVersion(packageName);
80
- if (version) {
81
- cache[packageName] = {
82
- version,
83
- timestamp: now,
84
- };
85
- writeVersionCache(cwd, cache);
86
- }
87
- return version;
88
- };
89
- const runStatusCommand = async (options, cwd = process.cwd()) => {
90
- const destDir = _package.findGitRoot(cwd) ?? cwd;
91
- const meta = syncMeta.readUnifiedSyncMeta(destDir);
92
- if (!meta || Object.keys(meta.packages).length === 0) {
93
- logger.logger.info('No packages synced yet.');
94
- return;
95
- }
96
- const statuses = [];
97
- for (const [, packageInfo] of Object.entries(meta.packages)) {
98
- let remoteVersion;
99
- let error;
100
- if (!options.noRemote) {
101
- try {
102
- remoteVersion = await getCachedRemoteVersion(packageInfo.originalName, destDir);
103
- }
104
- catch (err) {
105
- error = err instanceof Error ? err.message : 'Unknown error';
106
- }
107
- }
108
- const upToDate = remoteVersion !== undefined && remoteVersion === packageInfo.version;
109
- let totalFiles = 0;
110
- for (const files of Object.values(packageInfo.files)) {
111
- totalFiles += Array.isArray(files) ? files.length : 0;
112
- }
113
- statuses.push({
114
- name: packageInfo.originalName,
115
- localVersion: packageInfo.version,
116
- remoteVersion,
117
- upToDate,
118
- syncedAt: meta.syncedAt,
119
- error,
120
- files: packageInfo.files,
121
- fileCount: totalFiles,
122
- });
123
- }
124
- statuses.sort((a, b) => a.name.localeCompare(b.name));
125
- if (process.stdout.isTTY) {
126
- const packages = statuses.map((s) => ({
127
- name: s.name,
128
- localVersion: s.localVersion,
129
- remoteVersion: s.remoteVersion,
130
- status: s.error
131
- ? 'error'
132
- : s.upToDate
133
- ? 'up-to-date'
134
- : s.remoteVersion
135
- ? 'outdated'
136
- : 'unknown',
137
- syncedAt: s.syncedAt,
138
- error: s.error,
139
- files: s.files,
140
- fileCount: s.fileCount,
141
- }));
142
- const summary = {
143
- upToDate: statuses.filter((s) => s.upToDate).length,
144
- outdated: statuses.filter((s) => s.remoteVersion && !s.upToDate).length,
145
- error: statuses.filter((s) => s.error).length,
146
- unknown: statuses.filter((s) => !s.remoteVersion && !s.error && !options.noRemote).length,
147
- };
148
- ink.render(React.createElement(StatusDisplay.StatusDisplay, {
149
- packages,
150
- loading: false,
151
- summary,
152
- }));
153
- }
154
- else {
155
- console.log(pc.bold('\nPackage Status:\n'));
156
- for (const status of statuses) {
157
- const icon = status.upToDate
158
- ? pc.green('✓')
159
- : status.remoteVersion
160
- ? pc.yellow('⚠')
161
- : pc.gray('?');
162
- console.log(` ${icon} ${pc.cyan(status.name)}`);
163
- console.log(` Local: ${status.localVersion}`);
164
- if (status.remoteVersion) {
165
- console.log(` Remote: ${status.remoteVersion}`);
166
- }
167
- else if (status.error) {
168
- console.log(` Remote: ${pc.red('Error:')} ${status.error}`);
169
- }
170
- else if (options.noRemote) {
171
- console.log(` Remote: ${pc.gray('(check skipped)')}`);
172
- }
173
- else {
174
- console.log(` Remote: ${pc.gray('(not available)')}`);
175
- }
176
- if (status.remoteVersion && !status.upToDate) {
177
- console.log(` Status: ${pc.yellow('Update available')}`);
178
- }
179
- else if (status.upToDate) {
180
- console.log(` Status: ${pc.green('Up to date')}`);
181
- }
182
- console.log(` Synced: ${new Date(status.syncedAt).toLocaleString()}`);
183
- console.log('');
184
- }
185
- const upToDateCount = statuses.filter((s) => s.upToDate).length;
186
- const updateAvailable = statuses.filter((s) => s.remoteVersion && !s.upToDate).length;
187
- if (!options.noRemote) {
188
- console.log(pc.gray(`Summary: ${upToDateCount} up to date, ${updateAvailable} updates available\n`));
189
- }
190
- }
191
- };
192
-
193
- exports.runStatusCommand = runStatusCommand;
@@ -1,6 +0,0 @@
1
- import type { StatusCommandOptions } from './types.js';
2
- /**
3
- * Run the status command
4
- * @param options - Status command options
5
- */
6
- export declare const runStatusCommand: (options: StatusCommandOptions, cwd?: string) => Promise<void>;
@@ -1,171 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import { render } from 'ink';
4
- import pc from 'picocolors';
5
- import React from 'react';
6
- import { StatusDisplay } from '../components/status/StatusDisplay.mjs';
7
- import 'react/jsx-runtime';
8
- import { readUnifiedSyncMeta } from '../core/syncMeta.mjs';
9
- import { logger } from '../utils/logger.mjs';
10
- import { findGitRoot } from '../utils/package.mjs';
11
-
12
- const CACHE_DURATION = 5 * 60 * 1000;
13
- const CACHE_FILE = '.sync-version-cache.json';
14
- const fetchRemoteVersion = async (packageName) => {
15
- try {
16
- const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
17
- signal: AbortSignal.timeout(5000),
18
- });
19
- if (!response.ok) {
20
- if (response.status === 404) {
21
- return undefined;
22
- }
23
- throw new Error(`HTTP ${response.status}`);
24
- }
25
- const data = await response.json();
26
- return data.version;
27
- }
28
- catch {
29
- return undefined;
30
- }
31
- };
32
- const readVersionCache = (cwd) => {
33
- try {
34
- const cachePath = path.join(cwd, '.claude', CACHE_FILE);
35
- const content = fs.readFileSync(cachePath, 'utf-8');
36
- return JSON.parse(content);
37
- }
38
- catch {
39
- return {};
40
- }
41
- };
42
- const writeVersionCache = (cwd, cache) => {
43
- try {
44
- const cachePath = path.join(cwd, '.claude', CACHE_FILE);
45
- fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2));
46
- }
47
- catch {
48
- }
49
- };
50
- const getCachedRemoteVersion = async (packageName, cwd) => {
51
- const cache = readVersionCache(cwd);
52
- const now = Date.now();
53
- const cached = cache[packageName];
54
- if (cached && now - cached.timestamp < CACHE_DURATION) {
55
- return cached.version;
56
- }
57
- const version = await fetchRemoteVersion(packageName);
58
- if (version) {
59
- cache[packageName] = {
60
- version,
61
- timestamp: now,
62
- };
63
- writeVersionCache(cwd, cache);
64
- }
65
- return version;
66
- };
67
- const runStatusCommand = async (options, cwd = process.cwd()) => {
68
- const destDir = findGitRoot(cwd) ?? cwd;
69
- const meta = readUnifiedSyncMeta(destDir);
70
- if (!meta || Object.keys(meta.packages).length === 0) {
71
- logger.info('No packages synced yet.');
72
- return;
73
- }
74
- const statuses = [];
75
- for (const [, packageInfo] of Object.entries(meta.packages)) {
76
- let remoteVersion;
77
- let error;
78
- if (!options.noRemote) {
79
- try {
80
- remoteVersion = await getCachedRemoteVersion(packageInfo.originalName, destDir);
81
- }
82
- catch (err) {
83
- error = err instanceof Error ? err.message : 'Unknown error';
84
- }
85
- }
86
- const upToDate = remoteVersion !== undefined && remoteVersion === packageInfo.version;
87
- let totalFiles = 0;
88
- for (const files of Object.values(packageInfo.files)) {
89
- totalFiles += Array.isArray(files) ? files.length : 0;
90
- }
91
- statuses.push({
92
- name: packageInfo.originalName,
93
- localVersion: packageInfo.version,
94
- remoteVersion,
95
- upToDate,
96
- syncedAt: meta.syncedAt,
97
- error,
98
- files: packageInfo.files,
99
- fileCount: totalFiles,
100
- });
101
- }
102
- statuses.sort((a, b) => a.name.localeCompare(b.name));
103
- if (process.stdout.isTTY) {
104
- const packages = statuses.map((s) => ({
105
- name: s.name,
106
- localVersion: s.localVersion,
107
- remoteVersion: s.remoteVersion,
108
- status: s.error
109
- ? 'error'
110
- : s.upToDate
111
- ? 'up-to-date'
112
- : s.remoteVersion
113
- ? 'outdated'
114
- : 'unknown',
115
- syncedAt: s.syncedAt,
116
- error: s.error,
117
- files: s.files,
118
- fileCount: s.fileCount,
119
- }));
120
- const summary = {
121
- upToDate: statuses.filter((s) => s.upToDate).length,
122
- outdated: statuses.filter((s) => s.remoteVersion && !s.upToDate).length,
123
- error: statuses.filter((s) => s.error).length,
124
- unknown: statuses.filter((s) => !s.remoteVersion && !s.error && !options.noRemote).length,
125
- };
126
- render(React.createElement(StatusDisplay, {
127
- packages,
128
- loading: false,
129
- summary,
130
- }));
131
- }
132
- else {
133
- console.log(pc.bold('\nPackage Status:\n'));
134
- for (const status of statuses) {
135
- const icon = status.upToDate
136
- ? pc.green('✓')
137
- : status.remoteVersion
138
- ? pc.yellow('⚠')
139
- : pc.gray('?');
140
- console.log(` ${icon} ${pc.cyan(status.name)}`);
141
- console.log(` Local: ${status.localVersion}`);
142
- if (status.remoteVersion) {
143
- console.log(` Remote: ${status.remoteVersion}`);
144
- }
145
- else if (status.error) {
146
- console.log(` Remote: ${pc.red('Error:')} ${status.error}`);
147
- }
148
- else if (options.noRemote) {
149
- console.log(` Remote: ${pc.gray('(check skipped)')}`);
150
- }
151
- else {
152
- console.log(` Remote: ${pc.gray('(not available)')}`);
153
- }
154
- if (status.remoteVersion && !status.upToDate) {
155
- console.log(` Status: ${pc.yellow('Update available')}`);
156
- }
157
- else if (status.upToDate) {
158
- console.log(` Status: ${pc.green('Up to date')}`);
159
- }
160
- console.log(` Synced: ${new Date(status.syncedAt).toLocaleString()}`);
161
- console.log('');
162
- }
163
- const upToDateCount = statuses.filter((s) => s.upToDate).length;
164
- const updateAvailable = statuses.filter((s) => s.remoteVersion && !s.upToDate).length;
165
- if (!options.noRemote) {
166
- console.log(pc.gray(`Summary: ${upToDateCount} up to date, ${updateAvailable} updates available\n`));
167
- }
168
- }
169
- };
170
-
171
- export { runStatusCommand };
@@ -1,28 +0,0 @@
1
- 'use strict';
2
-
3
- var sync = require('../core/sync.cjs');
4
- var logger = require('../utils/logger.cjs');
5
-
6
- const runSyncCommand = async (options) => {
7
- if (options.package.length === 0) {
8
- logger.logger.error('No packages specified. Use -p <package> to specify packages.');
9
- logger.logger.info('Example: claude-assets-sync -p @canard/schema-form');
10
- process.exit(1);
11
- }
12
- if (options.dryRun)
13
- logger.logger.dryRunNotice();
14
- if (options.local)
15
- logger.logger.info('[LOCAL MODE] Reading packages from workspace instead of node_modules\n');
16
- const results = await sync.syncPackages(options.package, {
17
- force: options.force,
18
- dryRun: options.dryRun,
19
- local: options.local,
20
- ref: options.ref,
21
- flat: options.flat,
22
- });
23
- const hasFailures = results.some((r) => !r.success && !r.skipped);
24
- if (hasFailures)
25
- process.exit(1);
26
- };
27
-
28
- exports.runSyncCommand = runSyncCommand;
@@ -1,6 +0,0 @@
1
- import type { SyncCommandOptions } from './types.js';
2
- /**
3
- * Run the sync command
4
- * @param options - Sync command options
5
- */
6
- export declare const runSyncCommand: (options: SyncCommandOptions) => Promise<void>;
@@ -1,26 +0,0 @@
1
- import { syncPackages } from '../core/sync.mjs';
2
- import { logger } from '../utils/logger.mjs';
3
-
4
- const runSyncCommand = async (options) => {
5
- if (options.package.length === 0) {
6
- logger.error('No packages specified. Use -p <package> to specify packages.');
7
- logger.info('Example: claude-assets-sync -p @canard/schema-form');
8
- process.exit(1);
9
- }
10
- if (options.dryRun)
11
- logger.dryRunNotice();
12
- if (options.local)
13
- logger.info('[LOCAL MODE] Reading packages from workspace instead of node_modules\n');
14
- const results = await syncPackages(options.package, {
15
- force: options.force,
16
- dryRun: options.dryRun,
17
- local: options.local,
18
- ref: options.ref,
19
- flat: options.flat,
20
- });
21
- const hasFailures = results.some((r) => !r.success && !r.skipped);
22
- if (hasFailures)
23
- process.exit(1);
24
- };
25
-
26
- export { runSyncCommand };
@@ -1,89 +0,0 @@
1
- /**
2
- * Common types for command modules
3
- */
4
- import type { SkillUnit } from '../utils/types.js';
5
- /**
6
- * Base command result
7
- */
8
- export interface CommandResult {
9
- success: boolean;
10
- message?: string;
11
- }
12
- /**
13
- * Options for add command
14
- */
15
- export interface AddCommandOptions {
16
- package?: string;
17
- pattern?: string;
18
- local?: boolean;
19
- ref?: string;
20
- }
21
- /**
22
- * Options for sync command
23
- */
24
- export interface SyncCommandOptions {
25
- package: string[];
26
- force: boolean;
27
- dryRun: boolean;
28
- local: boolean;
29
- ref?: string;
30
- flat?: boolean;
31
- }
32
- /**
33
- * Options for list command
34
- */
35
- export interface ListCommandOptions {
36
- json?: boolean;
37
- }
38
- /**
39
- * Options for remove command
40
- */
41
- export interface RemoveCommandOptions {
42
- package: string;
43
- yes?: boolean;
44
- dryRun?: boolean;
45
- }
46
- /**
47
- * Options for status command
48
- */
49
- export interface StatusCommandOptions {
50
- noRemote?: boolean;
51
- }
52
- /**
53
- * Options for migrate command
54
- */
55
- export interface MigrateCommandOptions {
56
- dryRun?: boolean;
57
- }
58
- /**
59
- * Package list item
60
- */
61
- export interface PackageListItem {
62
- name: string;
63
- version: string;
64
- syncedAt: string;
65
- assetCount: number;
66
- assets: Record<string, number>;
67
- }
68
- /**
69
- * Package status item
70
- */
71
- export interface PackageStatusItem {
72
- name: string;
73
- localVersion: string;
74
- remoteVersion?: string;
75
- upToDate: boolean;
76
- syncedAt: string;
77
- error?: string;
78
- files: Record<string, SkillUnit[]>;
79
- fileCount: number;
80
- }
81
- /**
82
- * Remote version cache entry
83
- */
84
- export interface RemoteVersionCache {
85
- [packageName: string]: {
86
- version: string;
87
- timestamp: number;
88
- };
89
- }