cofluxd 0.1.2 → 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 +7 -4
- package/cofluxd.mjs +62 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,10 +11,11 @@ npm i -g cofluxd
|
|
|
11
11
|
## 用法
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
cofluxd #
|
|
14
|
+
cofluxd # 首次=交互式引导(问登记密钥/设备名,不问服务器地址),之后=看状态
|
|
15
15
|
cofluxd onboard # 显式重新走交互式配置
|
|
16
|
-
cofluxd up
|
|
17
|
-
cofluxd
|
|
16
|
+
cofluxd up # 零参数即可:起服务后打印浏览器授权链接,登录确认即完成登记
|
|
17
|
+
cofluxd up --enroll-key <KEY> # 走存量登记密钥流程(web「添加设备」给的命令)
|
|
18
|
+
cofluxd status # 服务器/登记(含"等待授权")/服务状态
|
|
18
19
|
cofluxd logs -f # 看 daemon 日志
|
|
19
20
|
cofluxd update # 更新二进制并重启(worker 另可由 server 远程热升级)
|
|
20
21
|
cofluxd reload # 改了 settings.json 后重启生效
|
|
@@ -22,7 +23,9 @@ cofluxd down # 停止
|
|
|
22
23
|
cofluxd uninstall [--purge] # 卸载(--purge 连二进制/配置/凭证一并删)
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
默认连公共服务 `wss://api.coflux.dev/daemon`(自托管用 `--server`
|
|
26
|
+
默认连公共服务 `wss://api.coflux.dev/daemon`(自托管用 `--server` 改;已保存的地址继续生效,非默认时会有醒目提示)。
|
|
27
|
+
|
|
28
|
+
不带 `--enroll-key` 时(推荐、默认):`cofluxd up` 起服务后会打印一个一次性授权链接,在浏览器用已登录的账号打开确认即可,无需先去 web 控制台生成密钥。仍可用 `--enroll-key`(从 web 控制台「添加设备」获取)走无头/脚本化登记。
|
|
26
29
|
|
|
27
30
|
## 配置
|
|
28
31
|
|
package/cofluxd.mjs
CHANGED
|
@@ -11,7 +11,6 @@ import { spawnSync } from "node:child_process";
|
|
|
11
11
|
|
|
12
12
|
// 默认中心服务(公共 SaaS);自托管用 --server 覆盖。
|
|
13
13
|
const DEFAULT_SERVER = "wss://api.coflux.dev/daemon";
|
|
14
|
-
const DEFAULT_WEB = "https://app.coflux.dev";
|
|
15
14
|
|
|
16
15
|
const REPO = "myWsq/coflux";
|
|
17
16
|
const HOME = process.env.COFLUX_HOME || join(homedir(), ".coflux");
|
|
@@ -19,6 +18,7 @@ const BIN_DIR = join(HOME, "bin");
|
|
|
19
18
|
const SETTINGS = join(HOME, "settings.json"); // 用户配置(含一次性登记密钥)→ daemon 直接读;含密钥故 600
|
|
20
19
|
const LOG_FILE = join(HOME, "daemon.log");
|
|
21
20
|
const CRED = join(HOME, "credentials.json");
|
|
21
|
+
const PENDING_AUTH = join(HOME, "pending-auth.json"); // worker 落盘的待授权链接(daemon.authorizePending)
|
|
22
22
|
const SUP_BIN = join(BIN_DIR, "coflux-supervisor");
|
|
23
23
|
const WRK_BIN = join(BIN_DIR, "coflux-worker");
|
|
24
24
|
const IS_MAC = platform() === "darwin";
|
|
@@ -40,6 +40,12 @@ function readSettings() {
|
|
|
40
40
|
try { return JSON.parse(fs.readFileSync(SETTINGS, "utf8")); } catch { return {}; }
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
function readPendingAuth() {
|
|
44
|
+
try { return JSON.parse(fs.readFileSync(PENDING_AUTH, "utf8")); } catch { return null; }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
48
|
+
|
|
43
49
|
async function download(url, dest) {
|
|
44
50
|
const res = await fetch(url, { redirect: "follow" });
|
|
45
51
|
if (!res.ok) die(`下载失败 HTTP ${res.status}: ${url}\n(该版本/平台的 release 资产是否已发布?)`);
|
|
@@ -157,12 +163,44 @@ function stopService() {
|
|
|
157
163
|
async function applyAndStart({ serverUrl, enrollKey, deviceName, shell, version, binDir, noStart }) {
|
|
158
164
|
await ensureBinaries({ version, binDir });
|
|
159
165
|
const settings = applyConfig({ serverUrl, enrollKey, deviceName, shell });
|
|
160
|
-
|
|
161
|
-
|
|
166
|
+
// 非默认服务器醒目提示:保存值/--server 仍生效(不强制覆盖),但防止 staging 之类残留值静默错连。
|
|
167
|
+
if (serverUrl !== DEFAULT_SERVER) {
|
|
168
|
+
console.log(`⚠ 使用非默认服务器: ${serverUrl}`);
|
|
162
169
|
}
|
|
163
170
|
installService(!noStart);
|
|
164
171
|
console.log(noStart ? "已安装(未启动)。" : `✓ daemon 已启动 → ${serverUrl}`);
|
|
165
|
-
|
|
172
|
+
if (!noStart && !settings.enrollKey && !fs.existsSync(CRED)) {
|
|
173
|
+
// 默认流程(零参数 up):无登记密钥、未登记 → 走浏览器授权,轮询 daemon 落盘的链接/凭证文件。
|
|
174
|
+
await waitForAuthorization();
|
|
175
|
+
} else {
|
|
176
|
+
cmdStatus();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 轮询 ~/.coflux/pending-auth.json(授权链接)与 credentials.json(登记成功)给出全程反馈。
|
|
181
|
+
// CLI 保持零协议:只读文件,不连 WS;daemon 断线重连会自动重发 enrollRequest、换发新链接。
|
|
182
|
+
async function waitForAuthorization() {
|
|
183
|
+
console.log("\n 等待设备授权 …\n");
|
|
184
|
+
const maxWaitMs = 11 * 60 * 1000; // 只是前台等待的上限;daemon 会持续自动续期授权链接,超时后用 status 看最新链接即可
|
|
185
|
+
const start = Date.now();
|
|
186
|
+
let printedUrl = null;
|
|
187
|
+
while (Date.now() - start < maxWaitMs) {
|
|
188
|
+
if (fs.existsSync(CRED)) {
|
|
189
|
+
console.log("✓ 设备已登记\n");
|
|
190
|
+
cmdStatus();
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const pending = readPendingAuth();
|
|
194
|
+
if (pending?.url && pending.url !== printedUrl) {
|
|
195
|
+
printedUrl = pending.url;
|
|
196
|
+
const mins = Number.isFinite(pending.expiresAt) ? Math.max(1, Math.round((pending.expiresAt - Date.now()) / 60000)) : null;
|
|
197
|
+
console.log(` 在浏览器打开以下链接,用已登录账号授权此设备${mins ? `(约 ${mins} 分钟内有效)` : ""}:\n`);
|
|
198
|
+
console.log(` ${pending.url}\n`);
|
|
199
|
+
}
|
|
200
|
+
await sleep(1000);
|
|
201
|
+
}
|
|
202
|
+
// 链接会过期换新(daemon 自动续期),别引导用户用"上面的链接"——过期后那是死链
|
|
203
|
+
console.log(" 仍未完成授权;daemon 已在后台运行并会自动更换过期的授权链接,用 `cofluxd status` 查看最新链接。\n");
|
|
166
204
|
}
|
|
167
205
|
|
|
168
206
|
/* ------------------------------ 命令 ------------------------------ */
|
|
@@ -180,13 +218,15 @@ async function cmdUp(v) {
|
|
|
180
218
|
|
|
181
219
|
async function cmdOnboard(v) {
|
|
182
220
|
const s = readSettings();
|
|
221
|
+
// 服务器地址不再交互询问(用户拍板 2026-07-04):--server > 已保存值 > 默认公共服务;
|
|
222
|
+
// 优先级与 cmdUp 一致(见 packages/cli/cofluxd.mjs 里 applyAndStart 的非默认提示)。
|
|
223
|
+
const serverUrl = v.server || s.serverUrl || DEFAULT_SERVER;
|
|
183
224
|
console.log("\n 欢迎使用 coflux —— 配置这台设备\n ──────────────────────────────\n");
|
|
225
|
+
console.log(` 服务器: ${serverUrl}\n`);
|
|
226
|
+
console.log(" 登记方式:留空走浏览器授权(推荐,起服务后打印链接,登录确认即可);\n 已有登记密钥可直接粘贴。\n");
|
|
184
227
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
185
228
|
try {
|
|
186
|
-
const
|
|
187
|
-
const web = serverUrl === DEFAULT_SERVER ? DEFAULT_WEB : "你的 coflux web 控制台";
|
|
188
|
-
console.log(`\n → 打开 ${web} 登录 →「添加设备」→ 复制登记密钥\n`);
|
|
189
|
-
const enrollKey = (await rl.question("登记密钥(已登记可留空): ")).trim();
|
|
229
|
+
const enrollKey = (v["enroll-key"] ?? (await rl.question("登记密钥(可留空): "))).trim();
|
|
190
230
|
const deviceName = (await rl.question(`设备名 [${s.deviceName || hostname()}]: `)).trim() || s.deviceName || hostname();
|
|
191
231
|
rl.close();
|
|
192
232
|
console.log("");
|
|
@@ -216,7 +256,17 @@ function cmdStatus() {
|
|
|
216
256
|
const s = readSettings();
|
|
217
257
|
console.log(`服务器: ${s.serverUrl || "(未配置)"}`);
|
|
218
258
|
console.log(`设备名: ${s.deviceName || "(默认)"}`);
|
|
219
|
-
|
|
259
|
+
const registered = fs.existsSync(CRED);
|
|
260
|
+
const pending = !registered ? readPendingAuth() : null;
|
|
261
|
+
if (registered) {
|
|
262
|
+
console.log("凭证: 已登记");
|
|
263
|
+
} else if (pending?.url) {
|
|
264
|
+
const mins = Number.isFinite(pending.expiresAt) ? Math.max(0, Math.round((pending.expiresAt - Date.now()) / 60000)) : null;
|
|
265
|
+
console.log(`凭证: 等待授权${mins !== null ? `(约 ${mins} 分钟内有效)` : ""}`);
|
|
266
|
+
console.log(` ${pending.url}`);
|
|
267
|
+
} else {
|
|
268
|
+
console.log("凭证: 未登记");
|
|
269
|
+
}
|
|
220
270
|
let running = false, active = "未运行";
|
|
221
271
|
if (IS_MAC) {
|
|
222
272
|
running = run("launchctl", ["list", "com.coflux.daemon"]).status === 0;
|
|
@@ -253,15 +303,15 @@ const HELP = `cofluxd —— coflux daemon 管理
|
|
|
253
303
|
|
|
254
304
|
cofluxd 首次=交互式配置(onboard),已配置=status
|
|
255
305
|
cofluxd onboard 交互式配置并启用
|
|
256
|
-
cofluxd up [flags]
|
|
306
|
+
cofluxd up [flags] 非交互装/起,零参数即可(不带 --enroll-key 时打印浏览器授权链接)
|
|
257
307
|
cofluxd reload 按 ~/.coflux/settings.json 重载并重启
|
|
258
308
|
cofluxd update 更新二进制并重启(worker 另可远程热升级)
|
|
259
|
-
cofluxd status
|
|
309
|
+
cofluxd status 服务器/登记(含"等待授权")/服务状态
|
|
260
310
|
cofluxd logs [-f] 看 daemon 日志
|
|
261
311
|
cofluxd down 停止
|
|
262
312
|
cofluxd uninstall [--purge] 卸载(--purge 连二进制/配置/凭证一并删)
|
|
263
313
|
|
|
264
|
-
up flags: --server <ws://.../daemon> --enroll-key <KEY
|
|
314
|
+
up flags: --server <ws://.../daemon> --enroll-key <KEY>(留空则走浏览器授权) --name <名> --shell <路径>
|
|
265
315
|
通用: --version <vX|latest>(默认 latest) --bin-dir <dir>(用本地 cargo 产物) --no-start
|
|
266
316
|
配置都在 ~/.coflux/settings.json(serverUrl/enrollKey/deviceName/shell,含密钥故 600),daemon 直接读;改后 cofluxd reload 生效。`;
|
|
267
317
|
|