nolo-cli 0.170.2 → 0.171.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.
- package/{chunk-2AALYZZF.js → chunk-6MXCQLLB.js} +50 -4
- package/{commandRegistry-OMHWU6IC.js → commandRegistry-HI2DPDAH.js} +5 -5
- package/index.js +45 -9
- package/package.json +1 -1
- package/{readlineWorkspace-XUUB3IXF.js → readlineWorkspace-67ZVVHVC.js} +1 -1
- package/{updateCommands-2IHLKRE2.js → updateCommands-BXGFH4VX.js} +1 -1
|
@@ -101,6 +101,42 @@ const { dirname, isAbsolute, join, normalize, relative } = require("node:path");
|
|
|
101
101
|
|
|
102
102
|
const payload = JSON.parse(Buffer.from(process.argv[2], "base64url").toString("utf8"));
|
|
103
103
|
const log = (line) => appendFileSync(payload.logPath, "[" + new Date().toISOString() + "] " + line + "\n", "utf8");
|
|
104
|
+
// 完成通知:best-effort。通知失败(无 PowerShell / 通知被禁用 / 无 notify-send)
|
|
105
|
+
// 一律静默,绝不能影响更新结果本身。
|
|
106
|
+
const notify = (title, message) => {
|
|
107
|
+
try {
|
|
108
|
+
if (process.platform === "win32") {
|
|
109
|
+
const psPath = join(process.env.SystemRoot || process.env.WINDIR || "C:\\\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
110
|
+
// 脚本里不含任何动态文本:title/message 经环境变量传入。
|
|
111
|
+
// 拼接转义永远追不上解释器认的引号集合(ASCII 单引号、弯引号 ‘ ’ 都会被当成引号),
|
|
112
|
+
// 所以这里不用引号包裹,直接用 $env: 取值。
|
|
113
|
+
const ps = [
|
|
114
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
115
|
+
"Add-Type -AssemblyName System.Drawing",
|
|
116
|
+
"$n = New-Object System.Windows.Forms.NotifyIcon",
|
|
117
|
+
"$n.Icon = [System.Drawing.SystemIcons]::Information",
|
|
118
|
+
"$n.Visible = $true",
|
|
119
|
+
"$n.ShowBalloonTip(6000, $env:NOLO_NOTIFY_TITLE, $env:NOLO_NOTIFY_MESSAGE, 'Info')",
|
|
120
|
+
"Start-Sleep -Milliseconds 800",
|
|
121
|
+
"$n.Dispose()",
|
|
122
|
+
].join("; ");
|
|
123
|
+
spawnSync(psPath, ["-NoProfile", "-NonInteractive", "-Command", ps], {
|
|
124
|
+
windowsHide: true,
|
|
125
|
+
timeout: 15000,
|
|
126
|
+
env: { ...process.env, NOLO_NOTIFY_TITLE: title, NOLO_NOTIFY_MESSAGE: message },
|
|
127
|
+
});
|
|
128
|
+
} else if (process.platform === "darwin") {
|
|
129
|
+
// 同理:AppleScript 通过 argv 取参,脚本正文是常量。
|
|
130
|
+
spawnSync(
|
|
131
|
+
"osascript",
|
|
132
|
+
["-e", "on run argv", "-e", "display notification (item 2 of argv) with title (item 1 of argv)", "-e", "end run", title, message],
|
|
133
|
+
{ timeout: 10000 },
|
|
134
|
+
);
|
|
135
|
+
} else {
|
|
136
|
+
spawnSync("notify-send", [title, message], { timeout: 10000 });
|
|
137
|
+
}
|
|
138
|
+
} catch {}
|
|
139
|
+
};
|
|
104
140
|
const runNpm = (args) => {
|
|
105
141
|
const command = [payload.nodePath, payload.npmCliPath, ...args].join(" ");
|
|
106
142
|
log("> " + command);
|
|
@@ -260,6 +296,8 @@ const switchWindowsShims = (shimDir, entrypoint) => {
|
|
|
260
296
|
updateId: payload.updateId,
|
|
261
297
|
lockPath: payload.lockPath,
|
|
262
298
|
};
|
|
299
|
+
let updateSucceeded = false;
|
|
300
|
+
let alreadyCurrent = false;
|
|
263
301
|
try {
|
|
264
302
|
// 2026-10-27 减法:不再等待父进程或其它 Nolo 窗口退出。
|
|
265
303
|
// 新版本写入独立版本目录、最后只切换入口,因此其它进程继续运行旧版本是安全的;
|
|
@@ -339,7 +377,9 @@ const switchWindowsShims = (shimDir, entrypoint) => {
|
|
|
339
377
|
log("Verified nolo-cli " + targetVersion + " at " + stagedEntrypoint);
|
|
340
378
|
} else {
|
|
341
379
|
log("Already current at " + targetVersion);
|
|
380
|
+
alreadyCurrent = true;
|
|
342
381
|
}
|
|
382
|
+
updateSucceeded = true;
|
|
343
383
|
} catch (error) {
|
|
344
384
|
const message = error && error.message ? error.message : String(error);
|
|
345
385
|
log("ERROR: " + message);
|
|
@@ -359,6 +399,12 @@ const switchWindowsShims = (shimDir, entrypoint) => {
|
|
|
359
399
|
}
|
|
360
400
|
} catch {}
|
|
361
401
|
try { rmSync(__filename, { force: true }); } catch {}
|
|
402
|
+
// 通知放在锁释放之后:同步通知最多阻塞十几秒,不能拖住下一次更新。
|
|
403
|
+
if (updateSucceeded) {
|
|
404
|
+
notify("Nolo", alreadyCurrent ? "Nolo is already up to date" : "Update finished - the next Nolo launch uses the new version");
|
|
405
|
+
} else {
|
|
406
|
+
notify("Nolo", "Update failed - see log: " + payload.logPath);
|
|
407
|
+
}
|
|
362
408
|
}
|
|
363
409
|
})();
|
|
364
410
|
`;
|
|
@@ -915,13 +961,13 @@ Nolo Agent CLI Installer & Updater
|
|
|
915
961
|
`);
|
|
916
962
|
output.write(`\u2713 Target channel: ${channel} (nolo-cli@${channel})
|
|
917
963
|
`);
|
|
918
|
-
output.write(`\u2713
|
|
964
|
+
output.write(`\u2713 Update scheduled in background (helper pid ${scheduled.helperPid}).
|
|
919
965
|
`);
|
|
920
|
-
output.write(`\u25B8
|
|
966
|
+
output.write(`\u25B8 You can keep using Nolo \u2014 no need to close this or any other window.
|
|
921
967
|
`);
|
|
922
|
-
output.write(`\u25B8
|
|
968
|
+
output.write(`\u25B8 Installation continues in the background; once it finishes, the next Nolo launch uses the new version.
|
|
923
969
|
`);
|
|
924
|
-
output.write(` Log: ${scheduled.logPath}
|
|
970
|
+
output.write(` Check version: nolo -v Log: ${scheduled.logPath}
|
|
925
971
|
|
|
926
972
|
`);
|
|
927
973
|
return { exitCode: 0, disposition: "scheduled" };
|
|
@@ -546,7 +546,7 @@ function getSystemInternalCommandEntries(renderHelpText2) {
|
|
|
546
546
|
return runDoctorRuntimeCommand(args, deps);
|
|
547
547
|
}),
|
|
548
548
|
createContextCommand(["doctor"], "Show CLI doctor information", async (_args, ctx) => {
|
|
549
|
-
const { buildCliDoctorText, getCliInstallChannel, resolveSelfUpdateServerUrl } = await import("./updateCommands-
|
|
549
|
+
const { buildCliDoctorText, getCliInstallChannel, resolveSelfUpdateServerUrl } = await import("./updateCommands-BXGFH4VX.js");
|
|
550
550
|
const { isCompiledBinary } = await import("./cliEnvHelpers-BVYTMUPJ.js");
|
|
551
551
|
const serverUrl = resolveSelfUpdateServerUrl(ctx.env);
|
|
552
552
|
console.log(
|
|
@@ -563,7 +563,7 @@ function getSystemInternalCommandEntries(renderHelpText2) {
|
|
|
563
563
|
return 0;
|
|
564
564
|
}),
|
|
565
565
|
createContextCommand(["update"], "Update the CLI", async (_args, ctx) => {
|
|
566
|
-
const { resolveSelfUpdateServerUrl, runSelfUpdate } = await import("./updateCommands-
|
|
566
|
+
const { resolveSelfUpdateServerUrl, runSelfUpdate } = await import("./updateCommands-BXGFH4VX.js");
|
|
567
567
|
return runSelfUpdate({
|
|
568
568
|
entrypointPath: ctx.entrypointPath,
|
|
569
569
|
serverUrl: resolveSelfUpdateServerUrl(ctx.env),
|
|
@@ -576,17 +576,17 @@ function getSystemInternalCommandEntries(renderHelpText2) {
|
|
|
576
576
|
return process.exitCode ?? 0;
|
|
577
577
|
}),
|
|
578
578
|
createContextCommand(["version"], "Show CLI version", async (_args, ctx) => {
|
|
579
|
-
const { buildCliVersionText } = await import("./updateCommands-
|
|
579
|
+
const { buildCliVersionText } = await import("./updateCommands-BXGFH4VX.js");
|
|
580
580
|
console.log(buildCliVersionText(ctx.packageInfo));
|
|
581
581
|
return 0;
|
|
582
582
|
}),
|
|
583
583
|
createContextCommand(["--version"], "Show CLI version", async (_args, ctx) => {
|
|
584
|
-
const { buildCliVersionText } = await import("./updateCommands-
|
|
584
|
+
const { buildCliVersionText } = await import("./updateCommands-BXGFH4VX.js");
|
|
585
585
|
console.log(buildCliVersionText(ctx.packageInfo));
|
|
586
586
|
return 0;
|
|
587
587
|
}),
|
|
588
588
|
createContextCommand(["-v"], "Show CLI version", async (_args, ctx) => {
|
|
589
|
-
const { buildCliVersionText } = await import("./updateCommands-
|
|
589
|
+
const { buildCliVersionText } = await import("./updateCommands-BXGFH4VX.js");
|
|
590
590
|
console.log(buildCliVersionText(ctx.packageInfo));
|
|
591
591
|
return 0;
|
|
592
592
|
}),
|
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
getWindowsUpdateStatus,
|
|
8
8
|
readPackageInfo
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6MXCQLLB.js";
|
|
10
10
|
import {
|
|
11
11
|
isCompiledBinary
|
|
12
12
|
} from "./chunk-WACI5I6V.js";
|
|
@@ -20,8 +20,34 @@ import "./chunk-G3SUCT4W.js";
|
|
|
20
20
|
import "./chunk-4VNS5WPM.js";
|
|
21
21
|
|
|
22
22
|
// packages/cli/index.ts
|
|
23
|
-
import { dirname, join } from "node:path";
|
|
23
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
24
24
|
import { fileURLToPath } from "node:url";
|
|
25
|
+
|
|
26
|
+
// packages/cli/versionChangeNotice.ts
|
|
27
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
28
|
+
import { homedir } from "node:os";
|
|
29
|
+
import { dirname, join } from "node:path";
|
|
30
|
+
var resolveNoticePath = (env, homeDir) => join(env.NOLO_HOME?.trim() || join(homeDir, ".nolo"), "cli", "last-run-version");
|
|
31
|
+
function takeVersionChangeNotice(currentVersion, options = {}) {
|
|
32
|
+
const env = options.env ?? process.env;
|
|
33
|
+
const homeDir = options.homeDir ?? homedir();
|
|
34
|
+
const noticePath = resolveNoticePath(env, homeDir);
|
|
35
|
+
let previous = "";
|
|
36
|
+
try {
|
|
37
|
+
previous = readFileSync(noticePath, "utf8").trim();
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
40
|
+
if (previous === currentVersion) return null;
|
|
41
|
+
try {
|
|
42
|
+
mkdirSync(dirname(noticePath), { recursive: true });
|
|
43
|
+
writeFileSync(noticePath, `${currentVersion}
|
|
44
|
+
`, "utf8");
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
return previous ? { from: previous, to: currentVersion } : null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// packages/cli/index.ts
|
|
25
51
|
var cliArgs = process.argv.slice(2);
|
|
26
52
|
var diagnostics = initializeDiagnostics(detectMode(cliArgs, process.env), process.env);
|
|
27
53
|
var logger = diagnostics.logger;
|
|
@@ -41,15 +67,25 @@ if (process.platform === "win32") {
|
|
|
41
67
|
process.exit(0);
|
|
42
68
|
}
|
|
43
69
|
}
|
|
44
|
-
var SOURCE_CLI_DIR =
|
|
45
|
-
var CLI_DIR = isCompiledBinary() ?
|
|
46
|
-
var ROOT_DIR =
|
|
47
|
-
var SCRIPT_DIR =
|
|
70
|
+
var SOURCE_CLI_DIR = dirname2(fileURLToPath(import.meta.url));
|
|
71
|
+
var CLI_DIR = isCompiledBinary() ? dirname2(process.execPath) : SOURCE_CLI_DIR;
|
|
72
|
+
var ROOT_DIR = join2(CLI_DIR, "..", "..");
|
|
73
|
+
var SCRIPT_DIR = join2(ROOT_DIR, "scripts");
|
|
48
74
|
var packageInfo = readPackageInfo();
|
|
75
|
+
var isScriptLikeArgs = cliArgs[0] === "update" || cliArgs[0] === "-v" || cliArgs[0] === "--version" || cliArgs.includes("--json");
|
|
76
|
+
if (process.stdout.isTTY && !isScriptLikeArgs) {
|
|
77
|
+
const change = takeVersionChangeNotice(packageInfo.version);
|
|
78
|
+
if (change) {
|
|
79
|
+
process.stderr.write(
|
|
80
|
+
`\u25B8 Nolo version changed: ${change.from} \u2192 ${change.to}
|
|
81
|
+
`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
49
85
|
var args = cliArgs;
|
|
50
86
|
async function runScript(script, forwardedArgs, env) {
|
|
51
87
|
const { spawnProcess } = await import("./processSpawn-SOAV3FEV.js");
|
|
52
|
-
const scriptPath =
|
|
88
|
+
const scriptPath = join2(SCRIPT_DIR, script);
|
|
53
89
|
const proc = spawnProcess({
|
|
54
90
|
cmd: [process.execPath, scriptPath, ...forwardedArgs],
|
|
55
91
|
stdin: "inherit",
|
|
@@ -60,7 +96,7 @@ async function runScript(script, forwardedArgs, env) {
|
|
|
60
96
|
return proc.exited;
|
|
61
97
|
}
|
|
62
98
|
async function launchTuiWorkspace(args2) {
|
|
63
|
-
const { startTuiWorkspace } = await import("./readlineWorkspace-
|
|
99
|
+
const { startTuiWorkspace } = await import("./readlineWorkspace-67ZVVHVC.js");
|
|
64
100
|
const { createTuiSummaryLlmCaller } = await import("./tuiSummaryLlmCaller-FQOEF4IE.js");
|
|
65
101
|
const { setCliAutoCompactionSummaryFallback } = await import("./localRuntimeAdapter-ZIAOTUBE.js");
|
|
66
102
|
setCliAutoCompactionSummaryFallback(
|
|
@@ -74,7 +110,7 @@ async function launchTuiWorkspace(args2) {
|
|
|
74
110
|
});
|
|
75
111
|
}
|
|
76
112
|
async function main() {
|
|
77
|
-
const { createCliRuntimeContext, looksLikeDaemonShortcut, renderHelpText, resolveCommand, runResolvedCommand } = await import("./commandRegistry-
|
|
113
|
+
const { createCliRuntimeContext, looksLikeDaemonShortcut, renderHelpText, resolveCommand, runResolvedCommand } = await import("./commandRegistry-HI2DPDAH.js");
|
|
78
114
|
const { buildCliRuntimeEnv, loadProfileConfig } = await import("./profileConfig-KN3N2BLF.js");
|
|
79
115
|
const { resolveTuiLaunchMode } = await import("./runtimeModeArgs-2Y7BALTO.js");
|
|
80
116
|
const runtimeEnv = {
|
package/package.json
CHANGED