@haposoft/cafekit 0.11.3 → 0.11.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/bin/install.js +1 -1
- package/bin/lib/i18n.js +36 -6
- package/bin/lib/version-check.js +101 -24
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -122,7 +122,7 @@ async function main() {
|
|
|
122
122
|
|
|
123
123
|
try {
|
|
124
124
|
ctx = buildContext(process.argv, `${Date.now()}`);
|
|
125
|
-
ctx.ui.intro(`${ctx.ui.pc.bgCyan(ctx.ui.pc.black(' CafeKit '))}Installer v${packageJson.version}
|
|
125
|
+
ctx.ui.intro(`${ctx.ui.pc.bgCyan(ctx.ui.pc.black(' CafeKit '))}${ctx.ui.pc.gray(' Installer')} v${packageJson.version}\n ${ctx.ui.pc.dim('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')}\n ${ctx.ui.pc.blue('📦 ' + (ctx.t ? ctx.t('introDesc') : 'AI-native development workflow'))}`);
|
|
126
126
|
if (got.reclaimed) ctx.ui.info(ctx.t('reclaimed'));
|
|
127
127
|
|
|
128
128
|
await selectLanguage(ctx);
|
package/bin/lib/i18n.js
CHANGED
|
@@ -37,6 +37,9 @@ const MESSAGES = {
|
|
|
37
37
|
modeDryRun: 'Mode: dry-run • no changes will be written',
|
|
38
38
|
modeInstall: 'Mode: install / update • your customisations are preserved',
|
|
39
39
|
|
|
40
|
+
// Intro
|
|
41
|
+
introDesc: 'AI-native development workflow for Claude Code',
|
|
42
|
+
|
|
40
43
|
// Platform install spinner
|
|
41
44
|
installingPlatform: 'Installing {name}',
|
|
42
45
|
platformInstalled: '{name} — {files} file(s), {skills} skill(s)',
|
|
@@ -94,8 +97,15 @@ const MESSAGES = {
|
|
|
94
97
|
outroDone: 'Done! docs: https://github.com/haposoft/cafekit',
|
|
95
98
|
|
|
96
99
|
// Version check
|
|
97
|
-
versionUpToDate:
|
|
98
|
-
versionDowngrade:
|
|
100
|
+
versionUpToDate: 'Already up to date ({v}). Use --force-overwrite to reinstall.',
|
|
101
|
+
versionDowngrade: 'Downgrading {from} → {to}. Features may be removed. Continue?',
|
|
102
|
+
versionSamePrompt: 'CafeKit {v} is already installed. What would you like to do?',
|
|
103
|
+
versionForceReinstall: 'Reinstalling CafeKit {v} (--force-overwrite)...',
|
|
104
|
+
versionUpgradePrompt: 'CafeKit {from} → {to}: Update available!',
|
|
105
|
+
updateOption: 'Update to {v}',
|
|
106
|
+
reinstallOption: 'Reinstall (overwrite managed files)',
|
|
107
|
+
reinstallCurrentOption: 'Reinstall {v}',
|
|
108
|
+
skipOption: 'Skip (exit)'
|
|
99
109
|
},
|
|
100
110
|
|
|
101
111
|
// ─── 日本語 ─────────────────────────────────────────────────────────────────
|
|
@@ -118,6 +128,9 @@ const MESSAGES = {
|
|
|
118
128
|
modeDryRun: 'モード: ドライラン • ファイルへの変更はありません',
|
|
119
129
|
modeInstall: 'モード: インストール / 更新 • カスタマイズは保持されます',
|
|
120
130
|
|
|
131
|
+
// Intro
|
|
132
|
+
introDesc: 'Claude Code 向け AI ネイティブ開発ワークフロー',
|
|
133
|
+
|
|
121
134
|
installingPlatform: '{name} をインストール中',
|
|
122
135
|
platformInstalled: '{name} — {files} ファイル、{skills} スキル',
|
|
123
136
|
platformDryInstalled: '{name} — {files} ファイル、{skills} スキル [ドライラン]',
|
|
@@ -169,8 +182,15 @@ const MESSAGES = {
|
|
|
169
182
|
dryRunOnly: 'ドライラン完了 — ファイルへの変更はありませんでした。\n 変更を適用するには --dry-run なしで再実行してください。',
|
|
170
183
|
outroDone: '完了! ドキュメント: https://github.com/haposoft/cafekit',
|
|
171
184
|
|
|
172
|
-
versionUpToDate:
|
|
173
|
-
versionDowngrade:
|
|
185
|
+
versionUpToDate: '最新バージョンです({v})。再インストールするには --force-overwrite を使用してください。',
|
|
186
|
+
versionDowngrade: '{from} → {to} へのダウングレードです。機能が削除される可能性があります。続けますか?',
|
|
187
|
+
versionSamePrompt: 'CafeKit {v} は既にインストールされています。何をしますか?',
|
|
188
|
+
versionForceReinstall: 'CafeKit {v} を再インストール中 (--force-overwrite)...',
|
|
189
|
+
versionUpgradePrompt: 'CafeKit {from} → {to}: アップデートが利用可能です!',
|
|
190
|
+
updateOption: '{v} にアップデート',
|
|
191
|
+
reinstallOption: '再インストール(管理対象ファイルを上書き)',
|
|
192
|
+
reinstallCurrentOption: '{v} を再インストール',
|
|
193
|
+
skipOption: 'スキップ(終了)'
|
|
174
194
|
},
|
|
175
195
|
|
|
176
196
|
// ─── Tiếng Việt ─────────────────────────────────────────────────────────────
|
|
@@ -193,6 +213,9 @@ const MESSAGES = {
|
|
|
193
213
|
modeDryRun: 'Chế độ: dry-run • sẽ không thay đổi bất kỳ tệp nào',
|
|
194
214
|
modeInstall: 'Chế độ: cài / cập nhật • nội dung bạn tuỳ chỉnh được giữ nguyên',
|
|
195
215
|
|
|
216
|
+
// Intro
|
|
217
|
+
introDesc: 'Quy trình phát triển AI-native cho Claude Code',
|
|
218
|
+
|
|
196
219
|
installingPlatform: 'Đang cài {name}',
|
|
197
220
|
platformInstalled: '{name} — {files} tệp, {skills} skill',
|
|
198
221
|
platformDryInstalled: '{name} — {files} tệp, {skills} skill [dry-run]',
|
|
@@ -244,8 +267,15 @@ const MESSAGES = {
|
|
|
244
267
|
dryRunOnly: 'Dry-run hoàn tất — không có tệp nào thay đổi.\n Chạy lại không có --dry-run để áp dụng.',
|
|
245
268
|
outroDone: 'Xong! Tài liệu: https://github.com/haposoft/cafekit',
|
|
246
269
|
|
|
247
|
-
versionUpToDate:
|
|
248
|
-
versionDowngrade:
|
|
270
|
+
versionUpToDate: 'Đã là phiên bản mới nhất ({v}). Dùng --force-overwrite để cài lại.',
|
|
271
|
+
versionDowngrade: 'Đang hạ cấp {from} → {to}. Một số tính năng có thể bị xoá. Tiếp tục?',
|
|
272
|
+
versionSamePrompt: 'CafeKit {v} đã được cài đặt. Bạn muốn làm gì?',
|
|
273
|
+
versionForceReinstall: 'Đang cài lại CafeKit {v} (--force-overwrite)...',
|
|
274
|
+
versionUpgradePrompt: 'CafeKit {from} → {to}: Có bản cập nhật mới!',
|
|
275
|
+
updateOption: 'Cập nhật lên {v}',
|
|
276
|
+
reinstallOption: 'Cài lại (ghi đè file được quản lý)',
|
|
277
|
+
reinstallCurrentOption: 'Cài lại {v}',
|
|
278
|
+
skipOption: 'Bỏ qua (thoát)'
|
|
249
279
|
}
|
|
250
280
|
};
|
|
251
281
|
|
package/bin/lib/version-check.js
CHANGED
|
@@ -43,46 +43,123 @@ function getInstalledVersion(platformKey) {
|
|
|
43
43
|
/**
|
|
44
44
|
* Check versions for all selected platforms and decide whether to proceed.
|
|
45
45
|
* Sets ctx.cancelled on same-version (without --force) or unconfirmed downgrade.
|
|
46
|
+
* Shows interactive prompt when version differs, asking user what to do.
|
|
46
47
|
*/
|
|
47
48
|
async function checkVersions(ctx) {
|
|
48
49
|
if (ctx.dryRun) return ctx;
|
|
49
50
|
|
|
50
51
|
const incoming = packageJson.version;
|
|
52
|
+
const platformsWithInstall = [];
|
|
51
53
|
|
|
52
54
|
for (const key of ctx.platforms) {
|
|
53
55
|
const installed = getInstalledVersion(key);
|
|
54
|
-
if (
|
|
56
|
+
if (installed) {
|
|
57
|
+
platformsWithInstall.push({ key, installed });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// All fresh installs - skip version check, proceed normally
|
|
62
|
+
if (platformsWithInstall.length === 0) {
|
|
63
|
+
return ctx;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Get unique versions across all platforms
|
|
67
|
+
const uniqueVersions = [...new Set(platformsWithInstall.map(p => p.installed))];
|
|
68
|
+
const installedVersion = uniqueVersions.length === 1 ? uniqueVersions[0] : `${uniqueVersions.join(', ')}`;
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
// Determine overall comparison (assuming same version across platforms)
|
|
71
|
+
const firstPlatform = platformsWithInstall[0];
|
|
72
|
+
const cmp = cmpVersion(firstPlatform.installed, incoming);
|
|
57
73
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
ctx.ui.info(ctx.t ? ctx.t('
|
|
74
|
+
// ── Same version ───────────────────────────────────────────────────────────
|
|
75
|
+
if (cmp === 0) {
|
|
76
|
+
if (ctx.options.forceOverwrite) {
|
|
77
|
+
ctx.ui.info(ctx.t ? ctx.t('versionForceReinstall', { v: installedVersion }) : `Reinstalling CafeKit ${installedVersion} (--force-overwrite)...`);
|
|
78
|
+
return ctx;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!ctx.interactive) {
|
|
82
|
+
ctx.ui.info(ctx.t ? ctx.t('versionUpToDate', { v: installedVersion }) : `CafeKit ${installedVersion} is already up to date. Use --force-overwrite to reinstall.`);
|
|
62
83
|
ctx.cancelled = true;
|
|
63
84
|
return ctx;
|
|
64
85
|
}
|
|
65
86
|
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
ctx.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
// Show current vs new and ask what to do
|
|
88
|
+
const options = [
|
|
89
|
+
{ value: 'reinstall', label: ctx.t ? ctx.t('reinstallOption') : 'Reinstall (overwrite managed files)' },
|
|
90
|
+
{ value: 'skip', label: ctx.t ? ctx.t('skipOption') : 'Skip (exit)' }
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const answer = await ctx.ui.select({
|
|
94
|
+
message: ctx.t
|
|
95
|
+
? ctx.t('versionSamePrompt', { v: installedVersion })
|
|
96
|
+
: `CafeKit ${installedVersion} is already installed. What do you want to do?`,
|
|
97
|
+
options
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
if (ctx.ui.isCancel(answer) || answer === 'skip') {
|
|
101
|
+
ctx.cancelled = true;
|
|
102
|
+
return ctx;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (answer === 'reinstall') {
|
|
106
|
+
ctx.options.forceOverwrite = true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return ctx;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ── Upgrade available ───────────────────────────────────────────────────────
|
|
113
|
+
if (cmp < 0) {
|
|
114
|
+
if (!ctx.interactive) {
|
|
115
|
+
// Non-interactive: proceed with upgrade automatically
|
|
116
|
+
return ctx;
|
|
83
117
|
}
|
|
84
118
|
|
|
85
|
-
//
|
|
119
|
+
// Show current vs new and ask what to do
|
|
120
|
+
const options = [
|
|
121
|
+
{ value: 'update', label: ctx.t ? ctx.t('updateOption', { v: incoming }) : `Update to ${incoming}` },
|
|
122
|
+
{ value: 'reinstall', label: ctx.t ? ctx.t('reinstallCurrentOption', { v: firstPlatform.installed }) : `Reinstall ${firstPlatform.installed}` },
|
|
123
|
+
{ value: 'skip', label: ctx.t ? ctx.t('skipOption') : 'Skip (exit)' }
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const answer = await ctx.ui.select({
|
|
127
|
+
message: ctx.t
|
|
128
|
+
? ctx.t('versionUpgradePrompt', { from: firstPlatform.installed, to: incoming })
|
|
129
|
+
: `CafeKit ${firstPlatform.installed} → ${incoming}: Update available!`,
|
|
130
|
+
options
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (ctx.ui.isCancel(answer) || answer === 'skip') {
|
|
134
|
+
ctx.cancelled = true;
|
|
135
|
+
return ctx;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (answer === 'reinstall') {
|
|
139
|
+
ctx.options.forceOverwrite = true;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// 'update' proceeds normally (no special flag needed)
|
|
143
|
+
return ctx;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ── Downgrade ──────────────────────────────────────────────────────────────
|
|
147
|
+
if (cmp > 0) {
|
|
148
|
+
const msg = ctx.t
|
|
149
|
+
? ctx.t('versionDowngrade', { from: firstPlatform.installed, to: incoming })
|
|
150
|
+
: `Downgrading ${firstPlatform.installed} → ${incoming}. This may remove features.`;
|
|
151
|
+
|
|
152
|
+
if (!ctx.interactive) {
|
|
153
|
+
ctx.ui.warn ? ctx.ui.warn(msg + ' Downgrade aborted in non-interactive mode. Use --force-overwrite to proceed.') : console.warn(msg);
|
|
154
|
+
ctx.cancelled = true;
|
|
155
|
+
return ctx;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const yes = await ctx.ui.confirm({ message: msg + ' Continue?', initialValue: false });
|
|
159
|
+
if (!yes || ctx.ui.isCancel(yes)) {
|
|
160
|
+
ctx.cancelled = true;
|
|
161
|
+
return ctx;
|
|
162
|
+
}
|
|
86
163
|
}
|
|
87
164
|
|
|
88
165
|
return ctx;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.5",
|
|
4
4
|
"description": "Claude Code-first spec-driven workflow for AI coding assistants. Bundles CafeKit hapo: skills, runtime hooks, agents, and installer scaffolding.",
|
|
5
5
|
"author": "Haposoft <nghialt@haposoft.com>",
|
|
6
6
|
"license": "MIT",
|