mocode-ai 1.0.9 → 1.0.11
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/dist/commands/upgrade.js +38 -0
- package/dist/i18n/index.js +8 -0
- package/dist/repl/index.js +16 -9
- package/package.json +1 -1
package/dist/commands/upgrade.js
CHANGED
|
@@ -84,6 +84,44 @@ export async function checkVersion() {
|
|
|
84
84
|
const hasUpdate = latest ? compareSemver(latest, current) > 0 : false;
|
|
85
85
|
return { current, latest, hasUpdate };
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* 前台执行 npm install -g,实时输出到 REPL。
|
|
89
|
+
* Linux/macOS 下 Node 加载 JS 后通常不锁定文件,npm 可直接覆盖;
|
|
90
|
+
* 若目标平台确实锁定,会在输出里报 EBUSY/EPERM,用户根据提示退出后重试即可。
|
|
91
|
+
*/
|
|
92
|
+
export async function runUpgradeForeground(onOutput) {
|
|
93
|
+
const cmd = 'npm';
|
|
94
|
+
const args = ['install', '-g', `${PKG_NAME}@latest`];
|
|
95
|
+
let output = '';
|
|
96
|
+
if (isDevRun() || process.env.MOCODE_NO_SPAWN) {
|
|
97
|
+
const msg = '[upgrade] dev mode: skipped real npm install\n';
|
|
98
|
+
onOutput(msg);
|
|
99
|
+
return { ok: false, exitCode: null, output: msg };
|
|
100
|
+
}
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
const child = spawn(cmd, args, {
|
|
103
|
+
shell: true,
|
|
104
|
+
stdio: 'pipe',
|
|
105
|
+
windowsHide: true,
|
|
106
|
+
});
|
|
107
|
+
const collect = (data) => {
|
|
108
|
+
const chunk = data.toString();
|
|
109
|
+
output += chunk;
|
|
110
|
+
onOutput(chunk);
|
|
111
|
+
};
|
|
112
|
+
child.stdout?.on('data', collect);
|
|
113
|
+
child.stderr?.on('data', collect);
|
|
114
|
+
child.on('error', (err) => {
|
|
115
|
+
const msg = `[upgrade] spawn error: ${err.message}\n`;
|
|
116
|
+
output += msg;
|
|
117
|
+
onOutput(msg);
|
|
118
|
+
resolve({ ok: false, exitCode: null, output });
|
|
119
|
+
});
|
|
120
|
+
child.on('close', (code) => {
|
|
121
|
+
resolve({ ok: code === 0, exitCode: code, output });
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
87
125
|
/** 生成一个升级脚本,等当前 mocode 进程退出后再执行 `npm i -g`,避免 npm 无法覆盖正在运行的包文件。 */
|
|
88
126
|
function writeUpgradeScript(logPath, parentPid) {
|
|
89
127
|
const scriptDir = path.join(os.homedir(), '.mocode');
|
package/dist/i18n/index.js
CHANGED
|
@@ -242,6 +242,10 @@ const zhCN = {
|
|
|
242
242
|
'upgrade.hasUpdate': '发现新版本:当前 v{current} → 最新 v{latest}',
|
|
243
243
|
'upgrade.upgradeStarted': '已启动后台升级 → {version}',
|
|
244
244
|
'upgrade.upgradeHint': '后台升级进程已启动。当前 mocode 进程退出后才会执行 npm install -g mocode-ai@latest,完成后下次启动即生效。日志:~/.mocode/upgrade.log',
|
|
245
|
+
'upgrade.begin': '开始升级 mocode-ai → {version}',
|
|
246
|
+
'upgrade.completed': '升级完成,mocode 即将退出,请重新启动以使用新版本。',
|
|
247
|
+
'upgrade.failedWithCode': '升级失败(退出码 {code})。',
|
|
248
|
+
'upgrade.manualHint': '可尝试退出 mocode 后手动运行:npm install -g mocode-ai@latest',
|
|
245
249
|
'upgrade.devSkip': '当前为开发运行(tsx),已跳过真实 npm install,避免误改全局包。',
|
|
246
250
|
'upgrade.fetchFailed': '无法获取最新版本(请检查网络或 npm registry)。',
|
|
247
251
|
'upgrade.pkgName': '包名:mocode-ai',
|
|
@@ -493,6 +497,10 @@ const en = {
|
|
|
493
497
|
'upgrade.hasUpdate': 'New version available: v{current} → v{latest}',
|
|
494
498
|
'upgrade.upgradeStarted': 'Background upgrade started → {version}',
|
|
495
499
|
'upgrade.upgradeHint': 'Background upgrade process started. npm install -g mocode-ai@latest will run after you exit mocode. Log: ~/.mocode/upgrade.log',
|
|
500
|
+
'upgrade.begin': 'Starting upgrade mocode-ai → {version}',
|
|
501
|
+
'upgrade.completed': 'Upgrade complete. mocode will exit now; please restart to use the new version.',
|
|
502
|
+
'upgrade.failedWithCode': 'Upgrade failed (exit code {code}).',
|
|
503
|
+
'upgrade.manualHint': 'Try exiting mocode and run: npm install -g mocode-ai@latest',
|
|
496
504
|
'upgrade.devSkip': 'Running in dev mode (tsx); skipped real npm install to avoid touching the global package.',
|
|
497
505
|
'upgrade.fetchFailed': 'Unable to fetch the latest version (check network or npm registry).',
|
|
498
506
|
'upgrade.pkgName': 'Package: mocode-ai',
|
package/dist/repl/index.js
CHANGED
|
@@ -32,7 +32,7 @@ import fs from 'node:fs';
|
|
|
32
32
|
import path from 'node:path';
|
|
33
33
|
import { getSandboxRoot } from '../sandbox/root.js';
|
|
34
34
|
import { setCurrentSessionId, getCurrentSessionId } from '../session/state.js';
|
|
35
|
-
import { checkVersion, fetchLatestVersion, getCurrentVersion,
|
|
35
|
+
import { checkVersion, fetchLatestVersion, getCurrentVersion, runUpgradeForeground, } from '../commands/upgrade.js';
|
|
36
36
|
/**
|
|
37
37
|
* readline 的 prompt 必须是纯文本(无 ANSI):readline 按字符数算光标位置,
|
|
38
38
|
* 颜色码会让光标错位、编辑时漂移。颜色只用在直接 stdout.write 的横幅 / 工具行 / 回复。
|
|
@@ -1193,23 +1193,30 @@ export async function startRepl(initialHistory, sessionId, sandboxRootOverride,
|
|
|
1193
1193
|
layout.contentWrite(`${ui.dim}${t('upgrade.pkgName')}${ui.reset}\n`);
|
|
1194
1194
|
continue;
|
|
1195
1195
|
}
|
|
1196
|
-
// /upgrade 或 /upgrade now —
|
|
1196
|
+
// /upgrade 或 /upgrade now — 前台执行升级,实时显示 npm 输出
|
|
1197
1197
|
if (arg === '' || arg === 'now') {
|
|
1198
1198
|
const signal = startRunningListener(t('running.upgrading'));
|
|
1199
1199
|
try {
|
|
1200
|
-
// 先快速拉一次最新版本,给出一个明确的升级目标提示
|
|
1201
1200
|
const latest = await fetchLatestVersion();
|
|
1202
1201
|
const current = getCurrentVersion();
|
|
1203
1202
|
if (latest && latest === current) {
|
|
1204
1203
|
layout.contentWrite(`${ui.green}✓ ${t('upgrade.noUpdate', { version: current })}${ui.reset}\n`);
|
|
1205
1204
|
continue;
|
|
1206
1205
|
}
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1206
|
+
const target = latest ?? 'latest';
|
|
1207
|
+
layout.contentWrite(`${ui.cyan}● ${t('upgrade.begin', { version: target })}${ui.reset}\n`);
|
|
1208
|
+
const result = await runUpgradeForeground((chunk) => {
|
|
1209
|
+
layout.contentWrite(chunk);
|
|
1210
|
+
});
|
|
1211
|
+
if (result.ok) {
|
|
1212
|
+
layout.contentWrite(`\n${ui.green}${ui.bold}✓ ${t('upgrade.completed')}${ui.reset}\n`);
|
|
1213
|
+
// 给用户 2.5 秒看清提示,然后自动退出,下次启动即使用新版本。
|
|
1214
|
+
await new Promise((resolve) => setTimeout(resolve, 2500));
|
|
1215
|
+
break;
|
|
1216
|
+
}
|
|
1217
|
+
else {
|
|
1218
|
+
layout.contentWrite(`${ui.red}✗ ${t('upgrade.failedWithCode', { code: String(result.exitCode ?? 'unknown') })}${ui.reset}\n`);
|
|
1219
|
+
layout.contentWrite(`${ui.dim}${t('upgrade.manualHint')}${ui.reset}\n`);
|
|
1213
1220
|
}
|
|
1214
1221
|
}
|
|
1215
1222
|
catch (e) {
|