@pengfengagent/cli 0.0.0-stage → 0.0.76
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/README.md +338 -2
- package/dist/acceptance-report.html +5622 -0
- package/dist/index.js +585065 -0
- package/dist/maintenanceWorker.mjs +97 -0
- package/man/man1/lh.1 +223 -0
- package/man/man1/lobe.1 +1 -0
- package/man/man1/lobehub.1 +1 -0
- package/package.json +78 -4
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { rmSync } from "node:fs";
|
|
3
|
+
import { readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
//#region src/daemon/maintenanceWorker.ts
|
|
7
|
+
/** Atomic replacement lets the connected daemon read progress during installation. */
|
|
8
|
+
async function writeMaintenanceState(file, operation) {
|
|
9
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
10
|
+
await writeFile(temporary, JSON.stringify(operation), { mode: 384 });
|
|
11
|
+
await rename(temporary, file);
|
|
12
|
+
}
|
|
13
|
+
async function run(command, args, timeout) {
|
|
14
|
+
await new Promise((resolve, reject) => {
|
|
15
|
+
const child = spawn(command, args, {
|
|
16
|
+
stdio: "inherit",
|
|
17
|
+
timeout
|
|
18
|
+
});
|
|
19
|
+
child.once("error", reject);
|
|
20
|
+
child.once("close", (code, signal) => {
|
|
21
|
+
if (code === 0) resolve();
|
|
22
|
+
else reject(/* @__PURE__ */ new Error(`CLI maintenance command failed (${signal ?? code}). See lh connect logs.`));
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/** Runs from a private copy outside the package being replaced. No runtime package imports. */
|
|
27
|
+
async function runMaintenanceWorker(config, ready) {
|
|
28
|
+
const { entry, executable, operation, statePath } = config;
|
|
29
|
+
const persist = async () => {
|
|
30
|
+
await writeMaintenanceState(config.receiptPath, operation);
|
|
31
|
+
await writeMaintenanceState(statePath, operation);
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
if (config.install) await run(config.install.command, config.install.args, 18e4);
|
|
35
|
+
const { stdout } = await promisify(execFile)(executable, [entry, "--version"], { timeout: 3e4 });
|
|
36
|
+
if (stdout.trim() !== operation.targetVersion) throw new Error("Installed CLI version did not match the requested version. The existing connection was kept.");
|
|
37
|
+
operation.stage = "restarting";
|
|
38
|
+
await persist();
|
|
39
|
+
ready();
|
|
40
|
+
const deadline = Date.now() + 3e4;
|
|
41
|
+
while (true) {
|
|
42
|
+
try {
|
|
43
|
+
process.kill(config.parentPid, 0);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (error.code === "ESRCH") break;
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
if (Date.now() >= deadline) throw new Error("The previous CLI did not stop. No second daemon was started.");
|
|
49
|
+
await setTimeout$1(100);
|
|
50
|
+
}
|
|
51
|
+
if (!config.restartArgs) return;
|
|
52
|
+
await run(executable, [
|
|
53
|
+
entry,
|
|
54
|
+
...config.restartArgs,
|
|
55
|
+
"--daemon"
|
|
56
|
+
], 45e3);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
operation.stage = "failed";
|
|
59
|
+
operation.error = error instanceof Error ? error.message : String(error);
|
|
60
|
+
await persist();
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (process.argv[2] === "--maintenance-config") {
|
|
65
|
+
const configPath = process.argv[3];
|
|
66
|
+
const config = JSON.parse(await readFile(configPath, "utf8"));
|
|
67
|
+
await rm(configPath);
|
|
68
|
+
let started = false;
|
|
69
|
+
const timeout = setTimeout(() => process.disconnect?.(), 15e3);
|
|
70
|
+
process.once("message", () => {
|
|
71
|
+
started = true;
|
|
72
|
+
clearTimeout(timeout);
|
|
73
|
+
runMaintenanceWorker(config, () => {
|
|
74
|
+
if (!process.connected) throw new Error("The original daemon stopped during installation. Start the connection manually.");
|
|
75
|
+
process.send?.({ type: "ready-to-restart" });
|
|
76
|
+
}).catch((error) => {
|
|
77
|
+
console.error(error);
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
}).finally(async () => {
|
|
80
|
+
if (process.connected) process.disconnect();
|
|
81
|
+
await rm(process.argv[1], { force: true });
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
process.once("SIGTERM", () => {
|
|
85
|
+
rmSync(process.argv[1], { force: true });
|
|
86
|
+
process.exit(143);
|
|
87
|
+
});
|
|
88
|
+
process.once("disconnect", () => {
|
|
89
|
+
clearTimeout(timeout);
|
|
90
|
+
if (!started) {
|
|
91
|
+
process.exitCode = 1;
|
|
92
|
+
rm(process.argv[1], { force: true }).catch(console.error);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { runMaintenanceWorker, writeMaintenanceState };
|
package/man/man1/lh.1
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
.\" Code generated by `npm run man:generate`; DO NOT EDIT.
|
|
2
|
+
.\" Manual command details come from the Commander command tree.
|
|
3
|
+
.TH LH 1 "" "@pengfengagent/cli 0.0.76" "User Commands"
|
|
4
|
+
.SH NAME
|
|
5
|
+
lh \- PengFengAgent CLI \- manage and connect to PengFengAgent services
|
|
6
|
+
.SH SYNOPSIS
|
|
7
|
+
.B lh
|
|
8
|
+
[\fIOPTION\fR]...
|
|
9
|
+
[\fICOMMAND\fR]
|
|
10
|
+
.br
|
|
11
|
+
.B lobe
|
|
12
|
+
[\fIOPTION\fR]...
|
|
13
|
+
[\fICOMMAND\fR]
|
|
14
|
+
.br
|
|
15
|
+
.B lobehub
|
|
16
|
+
[\fIOPTION\fR]...
|
|
17
|
+
[\fICOMMAND\fR]
|
|
18
|
+
.SH DESCRIPTION
|
|
19
|
+
lh is the command\-line interface for PengFengAgent. It provides authentication, device gateway connectivity, content generation, resource search, and management commands for agents, files, models, providers, plugins, knowledge bases, threads, topics, and related resources.
|
|
20
|
+
.PP
|
|
21
|
+
For command-specific manuals, use the built-in manual command:
|
|
22
|
+
.PP
|
|
23
|
+
.RS
|
|
24
|
+
.B lh man
|
|
25
|
+
[\fICOMMAND\fR]...
|
|
26
|
+
.RE
|
|
27
|
+
.SH COMMANDS
|
|
28
|
+
.TP
|
|
29
|
+
.B tool\-worker
|
|
30
|
+
Internal command for isolated tool execution
|
|
31
|
+
.TP
|
|
32
|
+
.B login
|
|
33
|
+
Log in to PengFengAgent via browser (Device Code Flow) or configure API key server
|
|
34
|
+
.TP
|
|
35
|
+
.B logout
|
|
36
|
+
Log out and remove stored credentials
|
|
37
|
+
.TP
|
|
38
|
+
.B completion
|
|
39
|
+
Output shell completion script
|
|
40
|
+
.TP
|
|
41
|
+
.B man
|
|
42
|
+
Show a manual page for the CLI or a subcommand
|
|
43
|
+
.TP
|
|
44
|
+
.B connect
|
|
45
|
+
Connect to the device gateway and listen for tool calls
|
|
46
|
+
.TP
|
|
47
|
+
.B disconnect
|
|
48
|
+
Disconnect from the device gateway (alias for `connect stop`)
|
|
49
|
+
.TP
|
|
50
|
+
.B device
|
|
51
|
+
Manage connected devices
|
|
52
|
+
.TP
|
|
53
|
+
.B status
|
|
54
|
+
Check if gateway connection can be established
|
|
55
|
+
.TP
|
|
56
|
+
.B doctor
|
|
57
|
+
Diagnose this machine: runtime, endpoints, credentials, scope, device and agent readiness
|
|
58
|
+
.TP
|
|
59
|
+
.B doc
|
|
60
|
+
Manage documents
|
|
61
|
+
.TP
|
|
62
|
+
.B search
|
|
63
|
+
Search across local resources or the web
|
|
64
|
+
.TP
|
|
65
|
+
.B read
|
|
66
|
+
Read a LobeHub link as plain text via the API (e.g. a shared topic: https://lobehub.com/share/t/<id>), bypassing the Cloudflare\-protected web page
|
|
67
|
+
.TP
|
|
68
|
+
.B recall
|
|
69
|
+
Recall what happened around a topic: matching messages, conversations, goals and pages in one time window
|
|
70
|
+
.TP
|
|
71
|
+
.B kb
|
|
72
|
+
Manage knowledge bases, folders, documents, and files
|
|
73
|
+
.TP
|
|
74
|
+
.B memory
|
|
75
|
+
Manage user memories
|
|
76
|
+
.TP
|
|
77
|
+
.B agent
|
|
78
|
+
Manage agents
|
|
79
|
+
.TP
|
|
80
|
+
.B agent\-group
|
|
81
|
+
Manage agent groups
|
|
82
|
+
.TP
|
|
83
|
+
.B agent\-signal
|
|
84
|
+
Inspect and trigger Agent Signal source events
|
|
85
|
+
.TP
|
|
86
|
+
.B bot
|
|
87
|
+
Manage bot integrations
|
|
88
|
+
.TP
|
|
89
|
+
.B channel
|
|
90
|
+
Read the current Agent run’s Channel conversation
|
|
91
|
+
.TP
|
|
92
|
+
.B generate
|
|
93
|
+
Generate content (text, image, video, speech) Alias: gen.
|
|
94
|
+
.TP
|
|
95
|
+
.B goal
|
|
96
|
+
Run long\-horizon Goal Graphs
|
|
97
|
+
.TP
|
|
98
|
+
.B file
|
|
99
|
+
Manage files
|
|
100
|
+
.TP
|
|
101
|
+
.B artifact
|
|
102
|
+
Publish local pages as artifacts
|
|
103
|
+
.TP
|
|
104
|
+
.B hetero
|
|
105
|
+
Run heterogeneous agent CLIs (Amp / Claude Code / CodeBuddy / Codex / GitHub Copilot / Cursor / Factory Droid / Devin / Grok Build / Kimi Code / OpenCode / Pi / Qoder / TRAE CLI / DeepSeek Harness) and stream their output
|
|
106
|
+
.TP
|
|
107
|
+
.B skill
|
|
108
|
+
Manage agent skills
|
|
109
|
+
.TP
|
|
110
|
+
.B session\-group
|
|
111
|
+
Manage agent session groups
|
|
112
|
+
.TP
|
|
113
|
+
.B task
|
|
114
|
+
Manage agent tasks
|
|
115
|
+
.TP
|
|
116
|
+
.B thread
|
|
117
|
+
Manage message threads
|
|
118
|
+
.TP
|
|
119
|
+
.B topic
|
|
120
|
+
Manage conversation topics
|
|
121
|
+
.TP
|
|
122
|
+
.B trace
|
|
123
|
+
Inspect and replay recorded agent execution traces
|
|
124
|
+
.TP
|
|
125
|
+
.B message
|
|
126
|
+
Manage messages
|
|
127
|
+
.TP
|
|
128
|
+
.B model
|
|
129
|
+
Manage AI models
|
|
130
|
+
.TP
|
|
131
|
+
.B notify
|
|
132
|
+
Send a callback message to a topic and trigger the agent to process it
|
|
133
|
+
.TP
|
|
134
|
+
.B notification
|
|
135
|
+
Manage notification delivery settings (email, IM, inbox, push)
|
|
136
|
+
.TP
|
|
137
|
+
.B provider
|
|
138
|
+
Manage AI providers
|
|
139
|
+
.TP
|
|
140
|
+
.B project
|
|
141
|
+
Manage goal\-oriented projects
|
|
142
|
+
.TP
|
|
143
|
+
.B dashboard
|
|
144
|
+
Manage dashboards (boards of monitoring widgets)
|
|
145
|
+
.TP
|
|
146
|
+
.B widget
|
|
147
|
+
Build monitoring widgets: sandboxed scripts rendered as dashboard cards
|
|
148
|
+
.TP
|
|
149
|
+
.B plugin
|
|
150
|
+
Manage plugins
|
|
151
|
+
.TP
|
|
152
|
+
.B connector
|
|
153
|
+
Manage MCP connectors (user connectors and their synced tools)
|
|
154
|
+
.TP
|
|
155
|
+
.B workspace
|
|
156
|
+
Manage workspaces and the workspace scope commands run under Alias: ws.
|
|
157
|
+
.TP
|
|
158
|
+
.B user
|
|
159
|
+
Manage user account and settings
|
|
160
|
+
.TP
|
|
161
|
+
.B acceptance
|
|
162
|
+
Delivery acceptances: the cross\-round review loop (checks, feedback, decision)
|
|
163
|
+
.TP
|
|
164
|
+
.B whoami
|
|
165
|
+
Display current user information
|
|
166
|
+
.TP
|
|
167
|
+
.B usage
|
|
168
|
+
View usage statistics
|
|
169
|
+
.TP
|
|
170
|
+
.B eval
|
|
171
|
+
Manage evaluation workflows
|
|
172
|
+
.TP
|
|
173
|
+
.B migrate
|
|
174
|
+
Migrate data from external tools (OpenClaw, ChatGPT, Claude, etc.)
|
|
175
|
+
.TP
|
|
176
|
+
.B update
|
|
177
|
+
Update the PengFengAgent CLI to the latest published version
|
|
178
|
+
.SH OPTIONS
|
|
179
|
+
.TP
|
|
180
|
+
.B \-V, \-\-version
|
|
181
|
+
output the version number
|
|
182
|
+
.TP
|
|
183
|
+
.B \-h, \-\-help
|
|
184
|
+
display help for command
|
|
185
|
+
.SH FILES
|
|
186
|
+
.TP
|
|
187
|
+
.I ~/.lobehub/credentials.json
|
|
188
|
+
Encrypted access and refresh tokens.
|
|
189
|
+
.TP
|
|
190
|
+
.I ~/.lobehub/settings.json
|
|
191
|
+
CLI settings such as server and gateway URLs.
|
|
192
|
+
.TP
|
|
193
|
+
.I ~/.lobehub/daemon.pid
|
|
194
|
+
Background daemon PID file.
|
|
195
|
+
.TP
|
|
196
|
+
.I ~/.lobehub/daemon.status
|
|
197
|
+
Background daemon status metadata.
|
|
198
|
+
.TP
|
|
199
|
+
.I ~/.lobehub/daemon.log
|
|
200
|
+
Background daemon log output.
|
|
201
|
+
.PP
|
|
202
|
+
The base directory can be overridden with the
|
|
203
|
+
.B LOBEHUB_CLI_HOME
|
|
204
|
+
environment variable.
|
|
205
|
+
.SH EXAMPLES
|
|
206
|
+
.TP
|
|
207
|
+
.B lh login
|
|
208
|
+
Start interactive login in the browser.
|
|
209
|
+
.TP
|
|
210
|
+
.B lh connect \-\-daemon
|
|
211
|
+
Start the device gateway connection in the background.
|
|
212
|
+
.TP
|
|
213
|
+
.B lh search \-q "gpt\-5"
|
|
214
|
+
Search local resources for a query.
|
|
215
|
+
.TP
|
|
216
|
+
.B lh generate text "Write release notes"
|
|
217
|
+
Generate text from a prompt.
|
|
218
|
+
.TP
|
|
219
|
+
.B lh man generate
|
|
220
|
+
Show the built\-in manual for the generate command group.
|
|
221
|
+
.SH SEE ALSO
|
|
222
|
+
.BR lobe (1),
|
|
223
|
+
.BR lobehub (1)
|
package/man/man1/lobe.1
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.so man1/lh.1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.so man1/lh.1
|
package/package.json
CHANGED
|
@@ -1,6 +1,80 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pengfengagent/cli",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.76",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"lh": "dist/index.js",
|
|
7
|
+
"lobe": "dist/index.js",
|
|
8
|
+
"lobehub": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"man": [
|
|
11
|
+
"./man/man1/lh.1",
|
|
12
|
+
"./man/man1/lobe.1",
|
|
13
|
+
"./man/man1/lobehub.1"
|
|
14
|
+
],
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"man"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "bun scripts/ensureWorkspaceLinks.ts && tsdown && tsdown src/daemon/maintenanceWorker.ts --no-config --no-clean --format esm --target node22 && bun scripts/copyReportTemplate.ts",
|
|
21
|
+
"cli:link": "bun link",
|
|
22
|
+
"cli:unlink": "bun unlink",
|
|
23
|
+
"dev": "LOBEHUB_CLI_HOME=.lobehub-dev bun src/index.ts",
|
|
24
|
+
"man:generate": "bun src/man/generate.ts",
|
|
25
|
+
"prepublishOnly": "bun run --cwd ../workbench build:report && npm run build && bun scripts/copyReportTemplate.ts --require && npm run man:generate",
|
|
26
|
+
"test": "bunx vitest run --config vitest.config.mts --silent='passed-only'",
|
|
27
|
+
"test:coverage": "bunx vitest run --config vitest.config.mts --coverage",
|
|
28
|
+
"test:e2e": "bunx vitest run --config vitest.e2e.config.mts --silent='passed-only'",
|
|
29
|
+
"type-check": "tsc --noEmit"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@lydell/node-pty": "1.2.0-beta.15",
|
|
33
|
+
"ws": "^8.21.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@lobechat/agent-gateway-client": "workspace:*",
|
|
37
|
+
"@lobechat/agent-tracing": "workspace:*",
|
|
38
|
+
"@lobechat/const": "workspace:*",
|
|
39
|
+
"@lobechat/device-control": "workspace:*",
|
|
40
|
+
"@lobechat/device-gateway-client": "workspace:*",
|
|
41
|
+
"@lobechat/device-identity": "workspace:*",
|
|
42
|
+
"@lobechat/eval-rubric": "workspace:*",
|
|
43
|
+
"@lobechat/heterogeneous-agents": "workspace:*",
|
|
44
|
+
"@lobechat/html-artifact": "workspace:*",
|
|
45
|
+
"@lobechat/local-file-shell": "workspace:*",
|
|
46
|
+
"@lobechat/prompts": "workspace:*",
|
|
47
|
+
"@lobechat/tool-runtime": "workspace:*",
|
|
48
|
+
"@lobechat/types": "workspace:*",
|
|
49
|
+
"@lobechat/utils": "workspace:*",
|
|
50
|
+
"@modelcontextprotocol/client": "~2.4.0",
|
|
51
|
+
"@trpc/client": "^11.18.0",
|
|
52
|
+
"@types/node": "^24.13.2",
|
|
53
|
+
"@types/semver": "^7.7.1",
|
|
54
|
+
"@types/ws": "^8.18.1",
|
|
55
|
+
"commander": "^13.1.0",
|
|
56
|
+
"dayjs": "^1.11.21",
|
|
57
|
+
"debug": "^4.4.3",
|
|
58
|
+
"diff": "^8.0.4",
|
|
59
|
+
"es-toolkit": "^1.50.0",
|
|
60
|
+
"fast-glob": "^3.3.3",
|
|
61
|
+
"ignore": "^7.0.5",
|
|
62
|
+
"picocolors": "^1.1.1",
|
|
63
|
+
"semver": "^7.8.5",
|
|
64
|
+
"superjson": "^2.2.6",
|
|
65
|
+
"tinyexec": "^1.3.0",
|
|
66
|
+
"tree-kill": "^1.2.2",
|
|
67
|
+
"tsdown": "^0.21.10",
|
|
68
|
+
"typescript": "^6.0.3",
|
|
69
|
+
"url-join": "^5.0.0",
|
|
70
|
+
"vitest": "5.0.0",
|
|
71
|
+
"zod": "^4.4.3"
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=22.15"
|
|
75
|
+
},
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public",
|
|
78
|
+
"registry": "https://registry.npmjs.org"
|
|
79
|
+
}
|
|
80
|
+
}
|