@lobehub/cli 0.0.61 → 0.0.63

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.
@@ -0,0 +1,91 @@
1
+ import { execFile, spawn } from "node:child_process";
2
+ import { readFile, rename, rm, writeFile } from "node:fs/promises";
3
+ import { setTimeout as setTimeout$1 } from "node:timers/promises";
4
+ import { promisify } from "node:util";
5
+ //#region src/daemon/maintenanceWorker.ts
6
+ /** Atomic replacement lets the connected daemon read progress during installation. */
7
+ async function writeMaintenanceState(file, operation) {
8
+ const temporary = `${file}.${process.pid}.tmp`;
9
+ await writeFile(temporary, JSON.stringify(operation), { mode: 384 });
10
+ await rename(temporary, file);
11
+ }
12
+ async function run(command, args, timeout) {
13
+ await new Promise((resolve, reject) => {
14
+ const child = spawn(command, args, {
15
+ stdio: "inherit",
16
+ timeout
17
+ });
18
+ child.once("error", reject);
19
+ child.once("close", (code, signal) => {
20
+ if (code === 0) resolve();
21
+ else reject(/* @__PURE__ */ new Error(`CLI maintenance command failed (${signal ?? code}). See lh connect logs.`));
22
+ });
23
+ });
24
+ }
25
+ /** Runs from a private copy outside the package being replaced. No runtime package imports. */
26
+ async function runMaintenanceWorker(config, ready) {
27
+ const { entry, executable, operation, statePath } = config;
28
+ const persist = async () => {
29
+ await writeMaintenanceState(config.receiptPath, operation);
30
+ await writeMaintenanceState(statePath, operation);
31
+ };
32
+ try {
33
+ if (config.install) await run(config.install.command, config.install.args, 18e4);
34
+ const { stdout } = await promisify(execFile)(executable, [entry, "--version"], { timeout: 3e4 });
35
+ if (stdout.trim() !== operation.targetVersion) throw new Error("Installed CLI version did not match the requested version. The existing connection was kept.");
36
+ operation.stage = "restarting";
37
+ await persist();
38
+ ready();
39
+ const deadline = Date.now() + 3e4;
40
+ while (true) {
41
+ try {
42
+ process.kill(config.parentPid, 0);
43
+ } catch (error) {
44
+ if (error.code === "ESRCH") break;
45
+ throw error;
46
+ }
47
+ if (Date.now() >= deadline) throw new Error("The previous CLI did not stop. No second daemon was started.");
48
+ await setTimeout$1(100);
49
+ }
50
+ await run(executable, [
51
+ entry,
52
+ ...config.restartArgs,
53
+ "--daemon"
54
+ ], 45e3);
55
+ } catch (error) {
56
+ operation.stage = "failed";
57
+ operation.error = error instanceof Error ? error.message : String(error);
58
+ await persist();
59
+ throw error;
60
+ }
61
+ }
62
+ if (process.argv[2] === "--maintenance-config") {
63
+ const configPath = process.argv[3];
64
+ const config = JSON.parse(await readFile(configPath, "utf8"));
65
+ await rm(configPath);
66
+ let started = false;
67
+ const timeout = setTimeout(() => process.disconnect?.(), 15e3);
68
+ process.once("message", () => {
69
+ started = true;
70
+ clearTimeout(timeout);
71
+ runMaintenanceWorker(config, () => {
72
+ if (!process.connected) throw new Error("The original daemon stopped during installation. Start the connection manually.");
73
+ process.send?.({ type: "ready-to-restart" });
74
+ }).catch((error) => {
75
+ console.error(error);
76
+ process.exitCode = 1;
77
+ }).finally(async () => {
78
+ if (process.connected) process.disconnect();
79
+ await rm(process.argv[1], { force: true });
80
+ });
81
+ });
82
+ process.once("disconnect", () => {
83
+ clearTimeout(timeout);
84
+ if (!started) {
85
+ process.exitCode = 1;
86
+ rm(process.argv[1], { force: true }).catch(console.error);
87
+ }
88
+ });
89
+ }
90
+ //#endregion
91
+ export { runMaintenanceWorker, writeMaintenanceState };
package/man/man1/lh.1 CHANGED
@@ -1,6 +1,6 @@
1
1
  .\" Code generated by `npm run man:generate`; DO NOT EDIT.
2
2
  .\" Manual command details come from the Commander command tree.
3
- .TH LH 1 "" "@lobehub/cli 0.0.61" "User Commands"
3
+ .TH LH 1 "" "@lobehub/cli 0.0.63" "User Commands"
4
4
  .SH NAME
5
5
  lh \- LobeHub CLI \- manage and connect to LobeHub services
6
6
  .SH SYNOPSIS
@@ -93,7 +93,7 @@ Manage files
93
93
  Publish local pages as artifacts
94
94
  .TP
95
95
  .B hetero
96
- Run heterogeneous agent CLIs (Amp / Claude Code / CodeBuddy / Codex / Cursor / Factory Droid / Devin / Grok Build / Kimi Code / OpenCode / Pi / Qoder / TRAE CLI) and stream their output
96
+ Run heterogeneous agent CLIs (Amp / Claude Code / CodeBuddy / Codex / Cursor / Factory Droid / Devin / Grok Build / Kimi Code / OpenCode / Pi / Qoder / TRAE CLI / DeepSeek Harness) and stream their output
97
97
  .TP
98
98
  .B skill
99
99
  Manage agent skills
@@ -128,6 +128,12 @@ Manage AI providers
128
128
  .B project
129
129
  Manage goal\-oriented projects
130
130
  .TP
131
+ .B dashboard
132
+ Manage dashboards (boards of monitoring widgets)
133
+ .TP
134
+ .B widget
135
+ Build monitoring widgets: sandboxed scripts rendered as dashboard cards
136
+ .TP
131
137
  .B plugin
132
138
  Manage plugins
133
139
  .TP
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/cli",
3
- "version": "0.0.61",
3
+ "version": "0.0.63",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "lh": "dist/index.js",
@@ -17,6 +17,7 @@
17
17
  "man"
18
18
  ],
19
19
  "dependencies": {
20
+ "@lydell/node-pty": "1.2.0-beta.15",
20
21
  "ws": "^8.21.0"
21
22
  },
22
23
  "devDependencies": {
@@ -39,18 +40,18 @@
39
40
  "typescript": "^6.0.3",
40
41
  "url-join": "^5.0.0",
41
42
  "vitest": "5.0.0",
42
- "@lobechat/agent-gateway-client": "1.0.0",
43
43
  "@lobechat/const": "1.0.0",
44
44
  "@lobechat/device-control": "1.0.0",
45
+ "@lobechat/agent-gateway-client": "1.0.0",
45
46
  "@lobechat/agent-tracing": "1.0.0",
46
- "@lobechat/device-identity": "1.0.0",
47
- "@lobechat/device-gateway-client": "1.0.0",
48
47
  "@lobechat/eval-rubric": "1.0.0",
49
- "@lobechat/heterogeneous-agents": "1.0.0",
48
+ "@lobechat/device-gateway-client": "1.0.0",
49
+ "@lobechat/device-identity": "1.0.0",
50
50
  "@lobechat/html-artifact": "1.0.0",
51
51
  "@lobechat/local-file-shell": "1.0.0",
52
- "@lobechat/types": "1.0.0",
52
+ "@lobechat/heterogeneous-agents": "1.0.0",
53
53
  "@lobechat/tool-runtime": "1.0.0",
54
+ "@lobechat/types": "1.0.0",
54
55
  "@lobechat/utils": "1.0.0"
55
56
  },
56
57
  "engines": {
@@ -61,7 +62,7 @@
61
62
  "registry": "https://registry.npmjs.org"
62
63
  },
63
64
  "scripts": {
64
- "build": "bun scripts/ensureWorkspaceLinks.ts && tsdown",
65
+ "build": "bun scripts/ensureWorkspaceLinks.ts && tsdown && tsdown src/daemon/maintenanceWorker.ts --no-config --no-clean --format esm --target node22",
65
66
  "cli:link": "bun link",
66
67
  "cli:unlink": "bun unlink",
67
68
  "dev": "LOBEHUB_CLI_HOME=.lobehub-dev bun src/index.ts",