@khanhcan148/mk 0.1.4 → 0.1.5
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/package.json +1 -1
- package/src/commands/init.js +29 -8
- package/src/commands/update.js +32 -9
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -10,6 +10,7 @@ import { MANIFEST_FILENAME } from '../lib/constants.js';
|
|
|
10
10
|
import { resolveTokenOrLogin } from '../lib/auth.js';
|
|
11
11
|
import { writeToken, readStoredToken } from '../lib/config.js';
|
|
12
12
|
import { downloadAndExtractKit, cleanupTempDir } from '../lib/download.js';
|
|
13
|
+
import { fetchLatestRelease } from '../lib/releases.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Run the init command.
|
|
@@ -19,7 +20,8 @@ import { downloadAndExtractKit, cleanupTempDir } from '../lib/download.js';
|
|
|
19
20
|
* targetDir?: string,
|
|
20
21
|
* manifestPath?: string,
|
|
21
22
|
* scope?: 'project'|'global',
|
|
22
|
-
* dryRun?: boolean
|
|
23
|
+
* dryRun?: boolean,
|
|
24
|
+
* version?: string - Kit version to store in manifest (defaults to pkg.version when omitted)
|
|
23
25
|
* }} params
|
|
24
26
|
* @returns {Promise<{ files: Array, totalSize: number }>}
|
|
25
27
|
*/
|
|
@@ -29,7 +31,8 @@ export async function runInit(params = {}) {
|
|
|
29
31
|
targetDir = resolveTargetDir({ global: false }),
|
|
30
32
|
manifestPath = resolveManifestPath({ global: false }),
|
|
31
33
|
scope = 'project',
|
|
32
|
-
dryRun = false
|
|
34
|
+
dryRun = false,
|
|
35
|
+
version: explicitVersion
|
|
33
36
|
} = params;
|
|
34
37
|
|
|
35
38
|
// Guard: abort if already installed
|
|
@@ -61,8 +64,10 @@ export async function runInit(params = {}) {
|
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
|
|
64
|
-
// Write manifest
|
|
65
|
-
|
|
67
|
+
// Write manifest.
|
|
68
|
+
// Use explicitVersion when provided (e.g. release.version from initAction);
|
|
69
|
+
// fall back to pkg.version for direct runInit calls without a known release version.
|
|
70
|
+
writeManifest(manifestPath, files, explicitVersion ?? pkg.version, scope);
|
|
66
71
|
|
|
67
72
|
const totalSize = fileList.reduce((s, f) => s + f.size, 0);
|
|
68
73
|
return { files: fileList, totalSize, fileCount: fileList.length };
|
|
@@ -81,11 +86,15 @@ export async function initAction(options = {}, deps = {}) {
|
|
|
81
86
|
downloadAndExtractKit: download = downloadAndExtractKit,
|
|
82
87
|
cleanupTempDir: cleanup = cleanupTempDir,
|
|
83
88
|
writeToken: storeToken = writeToken,
|
|
84
|
-
readStoredToken: readToken = readStoredToken
|
|
89
|
+
readStoredToken: readToken = readStoredToken,
|
|
90
|
+
fetchLatestRelease: fetchRelease = fetchLatestRelease,
|
|
91
|
+
// Injectable for tests — allows overriding resolved paths without touching CWD
|
|
92
|
+
targetDir: injectedTargetDir,
|
|
93
|
+
manifestPath: injectedManifestPath
|
|
85
94
|
} = deps;
|
|
86
95
|
|
|
87
|
-
const targetDir = resolveTargetDir(options);
|
|
88
|
-
const manifestPath = resolveManifestPath(options);
|
|
96
|
+
const targetDir = injectedTargetDir ?? resolveTargetDir(options);
|
|
97
|
+
const manifestPath = injectedManifestPath ?? resolveManifestPath(options);
|
|
89
98
|
const scope = options.global ? 'global' : 'project';
|
|
90
99
|
|
|
91
100
|
// Pre-flight: warn if target exists with files
|
|
@@ -115,11 +124,23 @@ export async function initAction(options = {}, deps = {}) {
|
|
|
115
124
|
}
|
|
116
125
|
});
|
|
117
126
|
|
|
127
|
+
// Determine installed version from latest release (more accurate than pkg.version).
|
|
128
|
+
// Falls back silently to pkg.version if no release is available (new repo, API error, etc.)
|
|
129
|
+
let installedVersion;
|
|
130
|
+
if (!options.dryRun) {
|
|
131
|
+
try {
|
|
132
|
+
const release = await fetchRelease(token);
|
|
133
|
+
installedVersion = release.available ? release.version : undefined;
|
|
134
|
+
} catch {
|
|
135
|
+
// Ignore errors — version fallback handled by runInit
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
118
139
|
process.stdout.write('Downloading kit from GitHub...\n');
|
|
119
140
|
tempDir = await download(token);
|
|
120
141
|
const sourceDir = join(tempDir, '.claude');
|
|
121
142
|
|
|
122
|
-
const result = await runInit({ sourceDir, targetDir, manifestPath, scope, dryRun: options.dryRun });
|
|
143
|
+
const result = await runInit({ sourceDir, targetDir, manifestPath, scope, dryRun: options.dryRun, version: installedVersion });
|
|
123
144
|
|
|
124
145
|
if (options.dryRun) {
|
|
125
146
|
process.stdout.write(`Would install ${result.files.length} files:\n`);
|
package/src/commands/update.js
CHANGED
|
@@ -40,7 +40,8 @@ async function defaultPromptUser(question) {
|
|
|
40
40
|
* sourceDir?: string,
|
|
41
41
|
* targetDir?: string,
|
|
42
42
|
* manifestPath?: string,
|
|
43
|
-
* force?: boolean
|
|
43
|
+
* force?: boolean,
|
|
44
|
+
* version?: string - Kit version to store in manifest (defaults to pkg.version when omitted)
|
|
44
45
|
* }} params
|
|
45
46
|
* @returns {Promise<{ updated: string[], added: string[], removed: string[], conflicts: string[], unchanged: string[], upToDate: boolean }>}
|
|
46
47
|
*/
|
|
@@ -49,7 +50,8 @@ export async function runUpdate(params = {}) {
|
|
|
49
50
|
sourceDir = resolveSourceDir(),
|
|
50
51
|
targetDir = resolveTargetDir({ global: false }),
|
|
51
52
|
manifestPath = resolveManifestPath({ global: false }),
|
|
52
|
-
force = false
|
|
53
|
+
force = false,
|
|
54
|
+
version: explicitVersion
|
|
53
55
|
} = params;
|
|
54
56
|
|
|
55
57
|
// Read existing manifest
|
|
@@ -159,8 +161,10 @@ export async function runUpdate(params = {}) {
|
|
|
159
161
|
delete newFiles[relPath];
|
|
160
162
|
}
|
|
161
163
|
|
|
162
|
-
// Update manifest with new file map
|
|
163
|
-
|
|
164
|
+
// Update manifest with new file map.
|
|
165
|
+
// Use explicitVersion when provided (e.g. release.version from updateAction);
|
|
166
|
+
// fall back to pkg.version for direct runUpdate calls or main-branch fallback downloads.
|
|
167
|
+
updateManifest(manifestPath, newFiles, explicitVersion ?? pkg.version);
|
|
164
168
|
|
|
165
169
|
return {
|
|
166
170
|
updated: diff.updated,
|
|
@@ -190,16 +194,18 @@ export async function updateAction(options = {}, deps = {}) {
|
|
|
190
194
|
readStoredToken: readToken = readStoredToken,
|
|
191
195
|
fetchLatestRelease: fetchRelease = fetchLatestRelease,
|
|
192
196
|
compareVersions: cmpVersions = compareVersions,
|
|
193
|
-
promptUser = defaultPromptUser
|
|
197
|
+
promptUser = defaultPromptUser,
|
|
198
|
+
// Injectable for tests — allows overriding resolved paths without touching CWD
|
|
199
|
+
manifestPath: injectedManifestPath
|
|
194
200
|
} = deps;
|
|
195
201
|
|
|
196
|
-
// Read local package version
|
|
202
|
+
// Read local package version (used as fallback when manifest has no version)
|
|
197
203
|
const pkg = JSON.parse(
|
|
198
204
|
readFileSync(fileURLToPath(new URL('../../package.json', import.meta.url)), 'utf8')
|
|
199
205
|
);
|
|
200
206
|
|
|
201
207
|
const targetDir = resolveTargetDir(options);
|
|
202
|
-
const manifestPath = resolveManifestPath(options);
|
|
208
|
+
const manifestPath = injectedManifestPath ?? resolveManifestPath(options);
|
|
203
209
|
|
|
204
210
|
let tempDir = null;
|
|
205
211
|
try {
|
|
@@ -220,7 +226,20 @@ export async function updateAction(options = {}, deps = {}) {
|
|
|
220
226
|
process.stdout.write('Checking for updates...\n');
|
|
221
227
|
const release = await fetchRelease(token);
|
|
222
228
|
|
|
229
|
+
// Read installed version from manifest (more accurate than pkg.version which reflects
|
|
230
|
+
// the CLI package, not the downloaded kit files). Fall back to pkg.version if no manifest.
|
|
231
|
+
let installedVersion = pkg.version;
|
|
232
|
+
if (existsSync(manifestPath)) {
|
|
233
|
+
try {
|
|
234
|
+
const existingManifest = readManifest(manifestPath);
|
|
235
|
+
if (existingManifest?.version) installedVersion = existingManifest.version;
|
|
236
|
+
} catch {
|
|
237
|
+
// Manifest unreadable — proceed with pkg.version fallback
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
223
241
|
let downloadUrl; // undefined = use default (main branch)
|
|
242
|
+
let releaseVersion; // set when downloading from a specific release tarball
|
|
224
243
|
|
|
225
244
|
if (!release.available) {
|
|
226
245
|
// No release found or API error — warn and fall back to main branch
|
|
@@ -228,7 +247,7 @@ export async function updateAction(options = {}, deps = {}) {
|
|
|
228
247
|
chalk.yellow(`Warning: Could not check latest release (${release.reason}). Falling back to main branch.\n`)
|
|
229
248
|
);
|
|
230
249
|
} else {
|
|
231
|
-
const { needsUpdate, local, remote } = cmpVersions(
|
|
250
|
+
const { needsUpdate, local, remote } = cmpVersions(installedVersion, release.version);
|
|
232
251
|
|
|
233
252
|
if (!needsUpdate) {
|
|
234
253
|
process.stdout.write(chalk.green(`Already up to date (v${local}).\n`));
|
|
@@ -256,6 +275,7 @@ export async function updateAction(options = {}, deps = {}) {
|
|
|
256
275
|
}
|
|
257
276
|
|
|
258
277
|
downloadUrl = release.tarballUrl;
|
|
278
|
+
releaseVersion = release.version;
|
|
259
279
|
}
|
|
260
280
|
|
|
261
281
|
// --- Download and apply ---
|
|
@@ -263,7 +283,10 @@ export async function updateAction(options = {}, deps = {}) {
|
|
|
263
283
|
tempDir = await download(token, downloadUrl !== undefined ? { url: downloadUrl } : {});
|
|
264
284
|
const sourceDir = join(tempDir, '.claude');
|
|
265
285
|
|
|
266
|
-
|
|
286
|
+
// Pass releaseVersion so runUpdate stores it in the manifest.
|
|
287
|
+
// When falling back to main branch (no release), releaseVersion is undefined and
|
|
288
|
+
// runUpdate falls back to pkg.version — which is the correct behaviour for that path.
|
|
289
|
+
const result = await runUpdate({ sourceDir, targetDir, manifestPath, force: options.force, version: releaseVersion });
|
|
267
290
|
|
|
268
291
|
if (result.upToDate) {
|
|
269
292
|
process.stdout.write(chalk.green('Already up to date.\n'));
|