nodus-wechat 0.7.1 → 0.7.2
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 +4 -1
- package/bin/nodus-wechat.js +35 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ npx nodus-wechat doctor
|
|
|
19
19
|
npx nodus-wechat start
|
|
20
20
|
npx nodus-wechat start --no-install
|
|
21
21
|
npx nodus-wechat start --no-hermes
|
|
22
|
+
npx nodus-wechat start --no-dashboard
|
|
22
23
|
npx nodus-wechat start --docker
|
|
23
24
|
npx nodus-wechat status
|
|
24
25
|
npx nodus-wechat logs
|
|
@@ -50,11 +51,13 @@ the official OpeniLink installer.
|
|
|
50
51
|
- Installs the OpeniLink + webhook POC runtime at `~/.nodus-wechat/runtime`.
|
|
51
52
|
- Writes Hermes common settings to `~/.hermes/config.yaml`.
|
|
52
53
|
- Writes the AstraGate key to `~/.hermes/.env` as `ASTRAGATE_API_KEY`.
|
|
54
|
+
- Sets Hermes static UI/message language to Simplified Chinese with `display.language: zh`.
|
|
53
55
|
- Writes runtime `.env`, Docker Compose, webhook server, helper scripts, and the OpeniLink reply plugin.
|
|
54
56
|
- Stores gateway base URL, api key, model, Hermes paths, OpeniLink origin, webhook port, and runtime path.
|
|
55
57
|
- Checks Node.js, local configuration, Hermes files, runtime files, Python, OpeniLink CLI, optional Docker Compose availability, Hermes CLI availability, and WeChat app detection with `doctor`.
|
|
56
|
-
- Starts/stops Hermes Gateway, OpeniLink, and the local webhook with native host processes by default.
|
|
58
|
+
- Starts/stops Hermes Gateway, Hermes Dashboard, OpeniLink, and the local webhook with native host processes by default.
|
|
57
59
|
- Installs Hermes and OpeniLink automatically during `start` when the native CLIs are missing.
|
|
60
|
+
- Exposes the Hermes management/configuration UI at `http://127.0.0.1:9119`.
|
|
58
61
|
- Keeps Docker Compose available only when `--docker` is passed.
|
|
59
62
|
- Removes Nodus WeChat config/runtime files with `uninstall --yes`.
|
|
60
63
|
- Cleans Nodus WeChat config/runtime plus generated Hermes settings with `clean --yes`.
|
package/bin/nodus-wechat.js
CHANGED
|
@@ -15,6 +15,7 @@ const DEFAULT_OPENILINK_ORIGIN = "http://localhost:9800";
|
|
|
15
15
|
const DEFAULT_OPENILINK_RP_ID = "localhost";
|
|
16
16
|
const DEFAULT_OPENILINK_PORT = 9800;
|
|
17
17
|
const DEFAULT_WEBHOOK_PORT = 9811;
|
|
18
|
+
const DEFAULT_HERMES_DASHBOARD_PORT = 9119;
|
|
18
19
|
const TEMPLATE_DIR = path.join(__dirname, "..", "templates", "wechat-agent-poc");
|
|
19
20
|
|
|
20
21
|
function configHome() {
|
|
@@ -43,7 +44,7 @@ Usage:
|
|
|
43
44
|
nodus-wechat install-hermes
|
|
44
45
|
nodus-wechat install-openilink
|
|
45
46
|
nodus-wechat doctor
|
|
46
|
-
nodus-wechat start [--docker] [--no-install] [--no-hermes]
|
|
47
|
+
nodus-wechat start [--docker] [--no-install] [--no-hermes] [--no-dashboard]
|
|
47
48
|
nodus-wechat status [--docker]
|
|
48
49
|
nodus-wechat logs [--docker]
|
|
49
50
|
nodus-wechat stop [--docker]
|
|
@@ -56,7 +57,7 @@ Commands:
|
|
|
56
57
|
install-openilink
|
|
57
58
|
Install OpeniLink Hub native CLI with the official installer.
|
|
58
59
|
doctor Check local prerequisites and configuration.
|
|
59
|
-
start Start Hermes Gateway, OpeniLink, and webhook on the host by default.
|
|
60
|
+
start Start Hermes Gateway, Hermes Dashboard, OpeniLink, and webhook on the host by default.
|
|
60
61
|
status Show local process status.
|
|
61
62
|
logs Follow local runtime logs.
|
|
62
63
|
stop Stop the local runtime.
|
|
@@ -78,7 +79,7 @@ function parseArgs(argv) {
|
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
const key = item.slice(2);
|
|
81
|
-
if (key === "help" || key === "yes" || key === "install-hermes" || key === "docker" || key === "no-install" || key === "no-hermes") {
|
|
82
|
+
if (key === "help" || key === "yes" || key === "install-hermes" || key === "docker" || key === "no-install" || key === "no-hermes" || key === "no-dashboard") {
|
|
82
83
|
result[key] = true;
|
|
83
84
|
continue;
|
|
84
85
|
}
|
|
@@ -198,6 +199,7 @@ function buildHermesConfig(config) {
|
|
|
198
199
|
' - "all"',
|
|
199
200
|
"display:",
|
|
200
201
|
' tool_progress: "all"',
|
|
202
|
+
' language: "zh"',
|
|
201
203
|
"compression:",
|
|
202
204
|
" enabled: true",
|
|
203
205
|
"",
|
|
@@ -532,12 +534,14 @@ function commandPath(name) {
|
|
|
532
534
|
}
|
|
533
535
|
|
|
534
536
|
function hermesPath(config) {
|
|
537
|
+
const configuredHome = config?.hermes?.home || hermesHome();
|
|
538
|
+
const configuredVenvHermes = path.join(configuredHome, "hermes-agent", "venv", "bin", "hermes");
|
|
539
|
+
const defaultUserHermes = path.join(os.homedir(), ".local", "bin", "hermes");
|
|
540
|
+
const defaultHermesHome = path.join(os.homedir(), ".hermes");
|
|
535
541
|
return (
|
|
536
542
|
commandPath("hermes") ||
|
|
537
|
-
(fs.existsSync(
|
|
538
|
-
(
|
|
539
|
-
? path.join(config.hermes.home, "hermes-agent", "venv", "bin", "hermes")
|
|
540
|
-
: null)
|
|
543
|
+
(fs.existsSync(configuredVenvHermes) ? configuredVenvHermes : null) ||
|
|
544
|
+
(configuredHome === defaultHermesHome && fs.existsSync(defaultUserHermes) ? defaultUserHermes : null)
|
|
541
545
|
);
|
|
542
546
|
}
|
|
543
547
|
|
|
@@ -553,6 +557,17 @@ function logPath(config, name) {
|
|
|
553
557
|
return runtimePath(config, `${name}.log`);
|
|
554
558
|
}
|
|
555
559
|
|
|
560
|
+
function localProcessNames(options = {}) {
|
|
561
|
+
const names = ["hermes", "hermes-dashboard", "openilink", "webhook"];
|
|
562
|
+
if (options["no-hermes"]) {
|
|
563
|
+
return names.filter((name) => name !== "hermes" && name !== "hermes-dashboard");
|
|
564
|
+
}
|
|
565
|
+
if (options["no-dashboard"]) {
|
|
566
|
+
return names.filter((name) => name !== "hermes-dashboard");
|
|
567
|
+
}
|
|
568
|
+
return names;
|
|
569
|
+
}
|
|
570
|
+
|
|
556
571
|
function readPid(filePath) {
|
|
557
572
|
if (!fs.existsSync(filePath)) {
|
|
558
573
|
return null;
|
|
@@ -750,10 +765,17 @@ function startLocal(options) {
|
|
|
750
765
|
startManagedProcess(config, "openilink", oih, [], env);
|
|
751
766
|
if (hermes) {
|
|
752
767
|
startManagedProcess(config, "hermes", hermes, ["gateway", "run"], env);
|
|
768
|
+
if (!options["no-dashboard"]) {
|
|
769
|
+
startManagedProcess(config, "hermes-dashboard", hermes, ["dashboard", "--host", "127.0.0.1", "--port", String(DEFAULT_HERMES_DASHBOARD_PORT), "--no-open"], env);
|
|
770
|
+
}
|
|
753
771
|
} else {
|
|
754
772
|
console.log("hermes: skipped (--no-hermes)");
|
|
773
|
+
console.log("hermes-dashboard: skipped (--no-hermes)");
|
|
755
774
|
}
|
|
756
775
|
console.log(`OpeniLink Hub: ${config.openilink?.publicOrigin || DEFAULT_OPENILINK_ORIGIN}`);
|
|
776
|
+
if (hermes && !options["no-dashboard"]) {
|
|
777
|
+
console.log(`Hermes Dashboard: http://127.0.0.1:${DEFAULT_HERMES_DASHBOARD_PORT}`);
|
|
778
|
+
}
|
|
757
779
|
console.log(`Webhook health: http://127.0.0.1:${config.webhook?.port || DEFAULT_WEBHOOK_PORT}/health`);
|
|
758
780
|
return 0;
|
|
759
781
|
}
|
|
@@ -777,10 +799,12 @@ async function statusLocal() {
|
|
|
777
799
|
return 1;
|
|
778
800
|
}
|
|
779
801
|
|
|
780
|
-
for (const name of
|
|
802
|
+
for (const name of localProcessNames()) {
|
|
781
803
|
const pid = readPid(pidPath(config, name));
|
|
782
804
|
console.log(`${name}: ${processRunning(pid) ? `running (pid ${pid})` : "stopped"}`);
|
|
783
805
|
}
|
|
806
|
+
const dashboardHealth = await httpGet(`http://127.0.0.1:${DEFAULT_HERMES_DASHBOARD_PORT}`);
|
|
807
|
+
console.log(`hermes dashboard: ${dashboardHealth.ok ? `ok (${dashboardHealth.statusCode})` : "unreachable"}`);
|
|
784
808
|
const health = await httpGet(`http://127.0.0.1:${config.webhook?.port || DEFAULT_WEBHOOK_PORT}/health`);
|
|
785
809
|
console.log(`webhook health: ${health.ok ? `ok (${health.statusCode})` : "unreachable"}`);
|
|
786
810
|
return 0;
|
|
@@ -805,7 +829,7 @@ function logsLocal() {
|
|
|
805
829
|
return 1;
|
|
806
830
|
}
|
|
807
831
|
|
|
808
|
-
const files =
|
|
832
|
+
const files = localProcessNames().map((name) => logPath(config, name)).filter((filePath) => fs.existsSync(filePath));
|
|
809
833
|
if (files.length === 0) {
|
|
810
834
|
console.error("No local runtime logs found.");
|
|
811
835
|
return 1;
|
|
@@ -845,6 +869,7 @@ function stopLocal() {
|
|
|
845
869
|
|
|
846
870
|
stopManagedProcess(config, "webhook");
|
|
847
871
|
stopManagedProcess(config, "openilink");
|
|
872
|
+
stopManagedProcess(config, "hermes-dashboard");
|
|
848
873
|
stopManagedProcess(config, "hermes");
|
|
849
874
|
return 0;
|
|
850
875
|
}
|
|
@@ -903,7 +928,7 @@ function clean(options) {
|
|
|
903
928
|
|
|
904
929
|
const config = fs.existsSync(configPath()) ? readConfig() : null;
|
|
905
930
|
if (config) {
|
|
906
|
-
for (const name of ["webhook", "openilink", "hermes"]) {
|
|
931
|
+
for (const name of ["webhook", "openilink", "hermes-dashboard", "hermes"]) {
|
|
907
932
|
stopManagedProcess({ ...config, runtime: { ...config.runtime, dir: config.runtime?.dir || path.join(configHome(), "runtime") } }, name);
|
|
908
933
|
}
|
|
909
934
|
const docker = dockerComposeAvailable();
|