nodus-wechat 0.1.0 → 0.2.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # nodus-wechat
2
2
 
3
- Placeholder package for the upcoming Nodus WeChat local agent installer.
3
+ CLI skeleton for the upcoming Nodus WeChat local agent installer.
4
4
 
5
5
  Run:
6
6
 
@@ -8,10 +8,28 @@ Run:
8
8
  npx nodus-wechat
9
9
  ```
10
10
 
11
- Current behavior:
11
+ ## Commands
12
12
 
13
- - Prints a placeholder message.
14
- - Does not install Hermes, iLink, or sub2api integrations.
15
- - Does not read, upload, or write user configuration.
13
+ ```sh
14
+ npx nodus-wechat setup --api-key <your-sub2api-key>
15
+ npx nodus-wechat doctor
16
+ npx nodus-wechat start
17
+ npx nodus-wechat uninstall --yes
18
+ ```
19
+
20
+ ## Current behavior
21
+
22
+ - Creates local configuration at `~/.nodus-wechat/config.json`.
23
+ - Stores sub2api base URL, api key, model, and local runtime status fields.
24
+ - Checks Node.js and local configuration with `doctor`.
25
+ - Reads configuration with `start` and reports that runtime integration is still pending.
26
+ - Removes only files created by this CLI with `uninstall --yes`.
27
+
28
+ ## Current non-goals
29
+
30
+ - Does not install Hermes.
31
+ - Does not install or run iLink.
32
+ - Does not automate, inject into, read, or control WeChat.
33
+ - Does not start a daemon, LaunchAgent, service, or background worker.
16
34
 
17
35
  The real installer will be released in a later version.
@@ -2,7 +2,236 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- console.log("Nodus WeChat installer is coming soon.");
6
- console.log("");
7
- console.log("Future purpose: install and configure a local WeChat Agent runtime.");
8
- console.log("This placeholder package does not read, upload, or write user configuration.");
5
+ const fs = require("node:fs");
6
+ const os = require("node:os");
7
+ const path = require("node:path");
8
+
9
+ const VERSION = "0.2";
10
+ const DEFAULT_BASE_URL = "https://api.nodus.sbs/v1";
11
+ const DEFAULT_MODEL = "gpt-5.5";
12
+
13
+ function configHome() {
14
+ return process.env.NODUS_WECHAT_HOME || path.join(os.homedir(), ".nodus-wechat");
15
+ }
16
+
17
+ function configPath() {
18
+ return path.join(configHome(), "config.json");
19
+ }
20
+
21
+ function printHelp() {
22
+ console.log(`nodus-wechat ${VERSION}
23
+
24
+ Local CLI skeleton for the upcoming Nodus WeChat Agent installer.
25
+
26
+ Usage:
27
+ nodus-wechat setup [--api-key <key>] [--base-url <url>] [--model <model>]
28
+ nodus-wechat doctor
29
+ nodus-wechat start
30
+ nodus-wechat uninstall --yes
31
+
32
+ Commands:
33
+ setup Create or update local configuration.
34
+ doctor Check local prerequisites and configuration.
35
+ start Read configuration and show the current stub runtime status.
36
+ uninstall Remove files created by this CLI.
37
+
38
+ This version does not install Hermes, iLink, or control WeChat.`);
39
+ }
40
+
41
+ function parseArgs(argv) {
42
+ const result = { _: [] };
43
+
44
+ for (let index = 0; index < argv.length; index += 1) {
45
+ const item = argv[index];
46
+ if (!item.startsWith("--")) {
47
+ result._.push(item);
48
+ continue;
49
+ }
50
+
51
+ const key = item.slice(2);
52
+ if (key === "help" || key === "yes") {
53
+ result[key] = true;
54
+ continue;
55
+ }
56
+
57
+ const value = argv[index + 1];
58
+ if (!value || value.startsWith("--")) {
59
+ throw new Error(`Missing value for --${key}`);
60
+ }
61
+
62
+ result[key] = value;
63
+ index += 1;
64
+ }
65
+
66
+ return result;
67
+ }
68
+
69
+ function readConfig() {
70
+ return JSON.parse(fs.readFileSync(configPath(), "utf8"));
71
+ }
72
+
73
+ function writeConfig(config) {
74
+ fs.mkdirSync(configHome(), { recursive: true, mode: 0o700 });
75
+ fs.writeFileSync(configPath(), `${JSON.stringify(config, null, 2)}\n`, {
76
+ mode: 0o600,
77
+ });
78
+ }
79
+
80
+ function createConfig(options) {
81
+ const existing = fs.existsSync(configPath()) ? readConfig() : {};
82
+ const now = new Date().toISOString();
83
+
84
+ return {
85
+ schemaVersion: 1,
86
+ createdAt: existing.createdAt || now,
87
+ updatedAt: now,
88
+ sub2api: {
89
+ baseUrl: options["base-url"] || existing.sub2api?.baseUrl || DEFAULT_BASE_URL,
90
+ apiKey: options["api-key"] || process.env.NODUS_WECHAT_API_KEY || existing.sub2api?.apiKey || "",
91
+ },
92
+ agent: {
93
+ model: options.model || existing.agent?.model || DEFAULT_MODEL,
94
+ reasoningEffort: existing.agent?.reasoningEffort || "high",
95
+ approvalMode: existing.agent?.approvalMode || "wechat-confirm",
96
+ },
97
+ wechat: {
98
+ connector: "ilink",
99
+ appPath: existing.wechat?.appPath || null,
100
+ status: "pending",
101
+ },
102
+ hermes: {
103
+ status: "not_installed",
104
+ },
105
+ ilink: {
106
+ status: "not_installed",
107
+ },
108
+ };
109
+ }
110
+
111
+ function setup(options) {
112
+ const config = createConfig(options);
113
+ writeConfig(config);
114
+
115
+ console.log(`Config written: ${configPath()}`);
116
+ console.log(`Base URL: ${config.sub2api.baseUrl}`);
117
+ console.log(`Model: ${config.agent.model}`);
118
+ if (!config.sub2api.apiKey) {
119
+ console.log("Warning: sub2api api key is empty. Run setup again with --api-key when ready.");
120
+ }
121
+ console.log("Hermes/iLink integration is pending in this CLI version.");
122
+ }
123
+
124
+ function doctor() {
125
+ let ok = true;
126
+ const major = Number.parseInt(process.versions.node.split(".")[0], 10);
127
+ if (major >= 18) {
128
+ console.log(`node: ok (${process.version})`);
129
+ } else {
130
+ ok = false;
131
+ console.log(`node: failed (${process.version}); Node.js >=18 is required`);
132
+ }
133
+
134
+ try {
135
+ fs.mkdirSync(configHome(), { recursive: true, mode: 0o700 });
136
+ fs.accessSync(configHome(), fs.constants.W_OK);
137
+ console.log(`config directory: ok (${configHome()})`);
138
+ } catch (error) {
139
+ ok = false;
140
+ console.log(`config directory: failed (${error.message})`);
141
+ }
142
+
143
+ if (!fs.existsSync(configPath())) {
144
+ console.log(`config: missing (${configPath()})`);
145
+ return 1;
146
+ }
147
+
148
+ try {
149
+ const config = readConfig();
150
+ console.log("config: ok");
151
+ if (config.sub2api?.apiKey) {
152
+ console.log("sub2api: ok (api key configured)");
153
+ } else {
154
+ ok = false;
155
+ console.log("sub2api: failed (api key missing)");
156
+ }
157
+ console.log(`hermes: ${config.hermes?.status || "not_installed"}`);
158
+ console.log(`ilink: ${config.ilink?.status || "not_installed"}`);
159
+ console.log(`wechat: ${findWeChatApp() || "not detected"}`);
160
+ } catch (error) {
161
+ ok = false;
162
+ console.log(`config: failed (${error.message})`);
163
+ }
164
+
165
+ return ok ? 0 : 1;
166
+ }
167
+
168
+ function findWeChatApp() {
169
+ const candidates = ["/Applications/WeChat.app", "/Applications/微信.app"];
170
+ return candidates.find((candidate) => fs.existsSync(candidate)) || null;
171
+ }
172
+
173
+ function start() {
174
+ if (!fs.existsSync(configPath())) {
175
+ console.error(`Config missing: ${configPath()}`);
176
+ console.error("Run: nodus-wechat setup --api-key <key>");
177
+ return 1;
178
+ }
179
+
180
+ const config = readConfig();
181
+ console.log("Nodus WeChat runtime stub");
182
+ console.log(`Config: ${configPath()}`);
183
+ console.log(`Model: ${config.agent?.model || DEFAULT_MODEL}`);
184
+ console.log("Hermes/iLink are not integrated in this version.");
185
+ console.log("No WeChat automation, login access, or message handling has been started.");
186
+ return 0;
187
+ }
188
+
189
+ function uninstall(options) {
190
+ if (!options.yes) {
191
+ console.error("Refusing to uninstall without --yes.");
192
+ return 1;
193
+ }
194
+
195
+ fs.rmSync(configHome(), { recursive: true, force: true });
196
+ console.log(`Removed: ${configHome()}`);
197
+ return 0;
198
+ }
199
+
200
+ function main() {
201
+ let args;
202
+ try {
203
+ args = parseArgs(process.argv.slice(2));
204
+ } catch (error) {
205
+ console.error(error.message);
206
+ return 1;
207
+ }
208
+
209
+ const command = args._[0];
210
+ if (!command || args.help || command === "help") {
211
+ printHelp();
212
+ return 0;
213
+ }
214
+
215
+ if (command === "setup") {
216
+ setup(args);
217
+ return 0;
218
+ }
219
+
220
+ if (command === "doctor") {
221
+ return doctor();
222
+ }
223
+
224
+ if (command === "start") {
225
+ return start();
226
+ }
227
+
228
+ if (command === "uninstall") {
229
+ return uninstall(args);
230
+ }
231
+
232
+ console.error(`Unknown command: ${command}`);
233
+ printHelp();
234
+ return 1;
235
+ }
236
+
237
+ process.exitCode = main();
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "nodus-wechat",
3
- "version": "0.1.0",
4
- "description": "Placeholder CLI for the upcoming Nodus WeChat local agent installer.",
3
+ "version": "0.2.0",
4
+ "description": "CLI skeleton for the upcoming Nodus WeChat local agent installer.",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "bin": {
8
8
  "nodus-wechat": "bin/nodus-wechat.js"
9
9
  },
10
+ "scripts": {
11
+ "test": "node --test"
12
+ },
10
13
  "files": [
11
14
  "bin",
12
15
  "README.md",