@zi.yi/openclaw-easy 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 王子怡 (Ziyi Wang)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # @zi.yi/openclaw-easy
2
+
3
+ [![npm version](https://badge.fury.io/js/@hzzzzzz%2Fopenclaw-easy.svg)](https://www.npmjs.com/package/@zi.yi/openclaw-easy)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Install Size](https://packagephobia.com/badge?p=@zi.yi/openclaw-easy)](https://packagephobia.com/result?p=@zi.yi/openclaw-easy)
6
+
7
+ > **One-command setup for [OpenClaw](https://github.com/anthropics/openclaw) with built-in API key.**
8
+
9
+ OpenClaw 是一个自托管 AI 助手网关,可以连接 WhatsApp、Telegram、Discord 等聊天应用到 AI 编码助手。这个工具让你一键完成配置,内置 GLM-4-Flash 模型。
10
+
11
+ ## 特点
12
+
13
+ - **零配置** - 内置免费 API key,开箱即用
14
+ - **灵活** - 可以选择使用自己的 API key
15
+ - **一键安装** - 一条命令完成所有配置
16
+ - **安全** - API key 加密存储
17
+
18
+ ## 快速开始
19
+
20
+ ### 安装
21
+
22
+ ```bash
23
+ npm install -g @zi.yi/openclaw-easy
24
+ ```
25
+
26
+ ### 使用
27
+
28
+ **方式一:使用内置福利 API key(推荐)**
29
+
30
+ ```bash
31
+ openclaw-easy
32
+ ```
33
+
34
+ 默认配置:
35
+ - 模型:`glm-4-flash`(通过 zai provider)
36
+
37
+ **方式二:使用自己的 API key**
38
+
39
+ ```bash
40
+ # 命令行参数
41
+ openclaw-easy --openai-key sk-your-api-key-here
42
+
43
+ # 或环境变量
44
+ export OPENAI_API_KEY=sk-your-api-key-here
45
+ openclaw-easy
46
+ ```
47
+
48
+ 安装完成后,你可以通过以下方式与 OpenClaw 交互:
49
+
50
+ ```bash
51
+ # 打开 Web 控制面板
52
+ npx openclaw dashboard
53
+
54
+ # 或使用终端界面
55
+ npx openclaw tui
56
+
57
+ # 或直接发送消息
58
+ npx openclaw agent --message "你好"
59
+ ```
60
+
61
+ ## 工作原理
62
+
63
+ 1. 从内置配置或用户输入获取 API key
64
+ 2. 将配置写入 `~/.openclaw/.env`(API key、模型)
65
+ 3. 运行 OpenClaw 的 onboarding 流程
66
+ 4. 安装并启动 OpenClaw 守护进程
67
+
68
+ ## 常见问题
69
+
70
+ ### Q: 内置的是什么模型?
71
+
72
+ A: 内置的是 GLM-4-Flash 模型(通过 zai provider),适合日常使用。
73
+
74
+ ### Q: 如何更换模型?
75
+
76
+ A: 编辑 `~/.openclaw/.env`,修改 `OPENCLAW_MODEL` 环境变量。
77
+
78
+ ### Q: 卸载怎么办?
79
+
80
+ ```bash
81
+ npm uninstall -g @zi.yi/openclaw-easy
82
+ npx openclaw uninstall # 完全卸载 OpenClaw
83
+ ```
84
+
85
+ ## 文档
86
+
87
+ 详细使用指南请查看 [USER_GUIDE.md](USER_GUIDE.md)
88
+
89
+ ## 开发
90
+
91
+ ```bash
92
+ # 克隆仓库
93
+ git clone https://github.com/hzzzzz-1/openclaw-easy.git
94
+ cd openclaw-easy
95
+
96
+ # 安装依赖
97
+ npm install
98
+
99
+ # 本地测试
100
+ npm install -g .
101
+ openclaw-easy
102
+
103
+ # 发布到 npm(需要设置环境变量)
104
+ BUILTIN_API_KEY="your-api-key" BUILTIN_MODEL="glm-4.7-flash" npm publish --access public
105
+ ```
106
+
107
+ ## 致谢
108
+
109
+ - [OpenClaw](https://github.com/anthropics/openclaw) - 核心项目
110
+ - [GLM](https://open.bigmodel.cn/) - 提供内置 API 支持
111
+
112
+ ## GitHub 仓库
113
+
114
+ https://github.com/hzzzzz-1/openclaw-easy
115
+
116
+ ## License
117
+
118
+ [MIT](LICENSE) © 2026 王子怡 (Ziyi Wang)
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { spawnSync } from "node:child_process";
7
+ import { createRequire } from "node:module";
8
+ import { createInterface } from "node:readline";
9
+
10
+ const require = createRequire(import.meta.url);
11
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
+
13
+ // 内部密钥(混淆)
14
+ const _k = "openclaw-easy-secret-2026";
15
+ const _0 = "d"; // API key
16
+ const _1 = "m"; // model
17
+ const _2 = "v"; // version
18
+
19
+ // 解密函数(与加密工具对应)
20
+ const _d = (s) => {
21
+ try {
22
+ const b = Buffer.from(s, "base64").toString("utf8");
23
+ let r = "";
24
+ for (let i = 0; i < b.length; i++) {
25
+ r += String.fromCharCode(b.charCodeAt(i) ^ _k.charCodeAt(i % _k.length));
26
+ }
27
+ return r;
28
+ } catch (_) {
29
+ return "";
30
+ }
31
+ };
32
+
33
+ // 获取内置配置
34
+ function getBuiltinConfig() {
35
+ try {
36
+ const configPath = path.join(__dirname, "../lib/config.json");
37
+ const raw = fs.readFileSync(configPath, "utf8");
38
+ const _c = JSON.parse(raw);
39
+
40
+ return {
41
+ apiKey: _d(_c[_0]),
42
+ model: _d(_c[_1]),
43
+ version: _c[_2]
44
+ };
45
+ } catch (err) {
46
+ console.error("Configuration error. Please reinstall:\n npm install -g @hzzzzzz/openclaw-easy");
47
+ process.exit(1);
48
+ }
49
+ }
50
+
51
+ // 交互式询问
52
+ function askQuestion(query) {
53
+ const rl = createInterface({
54
+ input: process.stdin,
55
+ output: process.stdout
56
+ });
57
+
58
+ return new Promise((resolve) => {
59
+ rl.question(query, (answer) => {
60
+ rl.close();
61
+ resolve(answer.trim().toLowerCase());
62
+ });
63
+ });
64
+ }
65
+
66
+ const arg = (name) => {
67
+ const i = process.argv.indexOf(name);
68
+ return i >= 0 ? process.argv[i + 1] : undefined;
69
+ };
70
+
71
+ // 更新 OpenClaw 配置文件,设置模型
72
+ function updateOpenClawConfig(model) {
73
+ const configPath = path.join(os.homedir(), ".openclaw", "openclaw.json");
74
+
75
+ try {
76
+ if (!fs.existsSync(configPath)) {
77
+ return;
78
+ }
79
+
80
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
81
+
82
+ // 模型 provider 映射
83
+ let modelKey;
84
+ if (model.includes("trinity")) {
85
+ modelKey = `openrouter/${model}`;
86
+ } else if (model.startsWith("glm")) {
87
+ modelKey = `zai/glm-4-flash`;
88
+ } else if (model.startsWith("gpt")) {
89
+ modelKey = `openai/${model}`;
90
+ } else {
91
+ modelKey = model;
92
+ }
93
+
94
+ config.agents = config.agents || {};
95
+ config.agents.defaults = config.agents.defaults || {};
96
+ config.agents.defaults.models = {
97
+ [modelKey]: {
98
+ "alias": modelKey.includes("trinity") ? "Trinity" : modelKey.startsWith("zai") ? "GLM" : "GPT"
99
+ }
100
+ };
101
+ config.agents.defaults.model = {
102
+ "primary": modelKey
103
+ };
104
+
105
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
106
+ console.log("\n✓ 已使用内置免费模型");
107
+ } catch (err) {
108
+ console.error("警告: 无法更新 OpenClaw 配置:", err.message);
109
+ }
110
+ }
111
+
112
+ // 主流程
113
+ async function main() {
114
+ const builtinConfig = getBuiltinConfig();
115
+ const userApiKey = arg("--openai-key") || process.env.OPENAI_API_KEY;
116
+
117
+ let finalApiKey;
118
+ let finalModel = builtinConfig.model;
119
+
120
+ if (userApiKey) {
121
+ console.log("\n检测到你提供了自己的 API key。");
122
+ console.log(" [1] 使用你自己的 API key");
123
+ console.log(" [2] 使用内置的免费 API key");
124
+
125
+ const choice = await askQuestion("\n请选择 [1/2](默认 1):");
126
+
127
+ if (choice === "2" || choice === "内置" || choice === "福利") {
128
+ finalApiKey = builtinConfig.apiKey;
129
+ console.log("\n✓ 使用内置福利 API key");
130
+ } else {
131
+ finalApiKey = userApiKey;
132
+ console.log("\n✓ 使用你提供的 API key");
133
+ // 用户用自己的 key,不强制使用 GLM 配置
134
+ finalModel = null;
135
+ }
136
+ } else {
137
+ finalApiKey = builtinConfig.apiKey;
138
+ console.log("\n✓ 使用内置免费 API key");
139
+ }
140
+
141
+ // 写入 .env 文件
142
+ const envFile = path.join(os.homedir(), ".openclaw", ".env");
143
+ fs.mkdirSync(path.dirname(envFile), { recursive: true });
144
+
145
+ const lines = fs.existsSync(envFile) ? fs.readFileSync(envFile, "utf8").split(/\r?\n/) : [];
146
+
147
+ // 过滤掉旧的配置行(包括看起来像是 API key 延续的行)
148
+ const next = [];
149
+ let skipNext = false;
150
+ for (const line of lines) {
151
+ if (skipNext) {
152
+ skipNext = false;
153
+ continue;
154
+ }
155
+ if (line.startsWith("OPENAI_API_KEY=") ||
156
+ line.startsWith("OPENROUTER_API_KEY=") ||
157
+ line.startsWith("ZAI_API_KEY=") ||
158
+ line.startsWith("OPENCLAW_MODEL=")) {
159
+ // 如果这行以 = 结尾但没有内容,可能是换行的 key,跳过下一行
160
+ if (line.endsWith("=") || line.match(/KEY=$/)) {
161
+ skipNext = true;
162
+ }
163
+ continue;
164
+ }
165
+ // 跳过看起来像是 API key 延续的行(不以 = 开头且像 base64/key 格式)
166
+ if (line.match(/^[a-zA-Z0-9_-]{20,}$/) && !line.includes("=")) {
167
+ continue;
168
+ }
169
+ next.push(line);
170
+ }
171
+
172
+ // 根据模型选择对应的环境变量
173
+ if (finalModel && finalModel.includes("trinity")) {
174
+ next.push(`OPENROUTER_API_KEY=${finalApiKey}`);
175
+ next.push(`OPENCLAW_MODEL=openrouter/${finalModel}`);
176
+ } else if (finalModel && finalModel.startsWith("glm")) {
177
+ next.push(`ZAI_API_KEY=${finalApiKey}`);
178
+ next.push(`OPENCLAW_MODEL=zai/glm-4-flash`);
179
+ } else {
180
+ next.push(`OPENAI_API_KEY=${finalApiKey}`);
181
+ if (finalModel) {
182
+ next.push(`OPENCLAW_MODEL=${finalModel}`);
183
+ }
184
+ }
185
+ fs.writeFileSync(envFile, `${next.filter(Boolean).join("\n")}\n`, "utf8");
186
+
187
+ // 调用 OpenClaw onboard
188
+ const openclawCli = require.resolve("openclaw/cli-entry");
189
+
190
+ // 根据模型选择认证方式和 API key 参数
191
+ let authChoice = "openai-api-key";
192
+ let apiKeyParam = "--openai-api-key";
193
+
194
+ if (finalModel && finalModel.includes("trinity")) {
195
+ authChoice = "openrouter-api-key";
196
+ apiKeyParam = "--openrouter-api-key";
197
+ } else if (finalModel && finalModel.startsWith("glm")) {
198
+ authChoice = "zai-api-key";
199
+ apiKeyParam = "--zai-api-key";
200
+ }
201
+
202
+ const run = spawnSync(
203
+ process.execPath,
204
+ [
205
+ openclawCli,
206
+ "onboard",
207
+ "--non-interactive",
208
+ "--accept-risk",
209
+ "--flow",
210
+ "quickstart",
211
+ "--auth-choice",
212
+ authChoice,
213
+ apiKeyParam,
214
+ finalApiKey,
215
+ "--install-daemon"
216
+ ],
217
+ {
218
+ stdio: "inherit",
219
+ env: {
220
+ ...process.env,
221
+ ...(finalModel && {
222
+ OPENCLAW_MODEL: finalModel.includes("trinity")
223
+ ? `openrouter/${finalModel}`
224
+ : finalModel.startsWith("glm")
225
+ ? "zai/glm-4-flash"
226
+ : finalModel
227
+ })
228
+ }
229
+ }
230
+ );
231
+
232
+ // 如果使用内置配置,更新 openclaw.json
233
+ if (finalModel && run.status === 0) {
234
+ updateOpenClawConfig(finalModel);
235
+
236
+ // 停止 gateway(LaunchAgent 会自动重启)
237
+ console.log("\n正在重启 OpenClaw Gateway...");
238
+ spawnSync(
239
+ process.execPath,
240
+ [openclawCli, "gateway", "--stop"],
241
+ { stdio: "inherit" }
242
+ );
243
+ console.log("\n✓ 配置完成!Gateway 正在自动启动...");
244
+ console.log("\n运行以下命令打开控制面板:");
245
+ console.log(" npx openclaw dashboard");
246
+ }
247
+
248
+ process.exit(run.status ?? 1);
249
+ }
250
+
251
+ main().catch((err) => {
252
+ console.error("Error:", err);
253
+ process.exit(1);
254
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "_comment": "这是配置示例,实际使用时请复制为 config.json 并填入真实值",
3
+ "_note": "使用 node scripts/encrypt-config.mjs <api-key> <model> 生成加密配置",
4
+ "apiKey": "加密后的API密钥(base64)",
5
+ "model": "加密后的模型名(base64)",
6
+ "provider": "moonshot"
7
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "d": "HBtIARFBF0YAAVZKHx5DAwEWAE0dBlQFVVhHUApaVAdEG1dTEEgeRFVXQ1FDGwJWBAcOFgBeVF9ZFRxWAkYbHRZRWkUGF0xTUg==",
3
+ "m": "DgIGCwZBAB4CERMaF0QHHE4eBAZKVx1CRAoGDAsUVgcFSAA=",
4
+ "v": "1"
5
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@zi.yi/openclaw-easy",
3
+ "version": "1.0.0",
4
+ "description": "One-command setup for OpenClaw with built-in API key",
5
+ "type": "module",
6
+ "bin": {
7
+ "openclaw-easy": "bin/openclaw-easy.mjs"
8
+ },
9
+ "scripts": {
10
+ "prepack": "node scripts/prepack.mjs",
11
+ "postpack": "rm -f lib/config.json",
12
+ "test": "node bin/openclaw-easy.mjs --help"
13
+ },
14
+ "dependencies": {
15
+ "openclaw": "^2026.2.9"
16
+ },
17
+ "keywords": [
18
+ "openclaw",
19
+ "cli",
20
+ "setup",
21
+ "openai"
22
+ ],
23
+ "author": "王子怡 (Ziyi Wang) <3597792204@qq.com> (https://github.com/hzzzzz-1)",
24
+ "license": "MIT",
25
+ "engines": {
26
+ "node": ">=18.0.0"
27
+ },
28
+ "files": [
29
+ "bin/",
30
+ "lib/"
31
+ ]
32
+ }