cofluxd 0.2.0 → 0.3.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.
Files changed (2) hide show
  1. package/cofluxd.mjs +42 -1
  2. package/package.json +1 -1
package/cofluxd.mjs CHANGED
@@ -19,6 +19,7 @@ const SETTINGS = join(HOME, "settings.json"); // 用户配置(含一次性登
19
19
  const LOG_FILE = join(HOME, "daemon.log");
20
20
  const CRED = join(HOME, "credentials.json");
21
21
  const PENDING_AUTH = join(HOME, "pending-auth.json"); // worker 落盘的待授权链接(daemon.authorizePending)
22
+ const FDA_STATUS = join(HOME, "fda-status"); // supervisor 启动时探测落盘(仅 macOS,见 crates/supervisor/src/fda.rs)
22
23
  const SUP_BIN = join(BIN_DIR, "coflux-supervisor");
23
24
  const WRK_BIN = join(BIN_DIR, "coflux-worker");
24
25
  const IS_MAC = platform() === "darwin";
@@ -44,6 +45,14 @@ function readPendingAuth() {
44
45
  try { return JSON.parse(fs.readFileSync(PENDING_AUTH, "utf8")); } catch { return null; }
45
46
  }
46
47
 
48
+ // "granted" | "denied" | "unknown" | null(文件不存在——supervisor 还没起过/还没写)
49
+ function readFdaStatus() {
50
+ try { return fs.readFileSync(FDA_STATUS, "utf8").trim(); } catch { return null; }
51
+ }
52
+ function fdaLabel(status) {
53
+ return status === "granted" ? "已授予" : status === "denied" ? "未授予" : "未知";
54
+ }
55
+
47
56
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
48
57
 
49
58
  async function download(url, dest) {
@@ -175,6 +184,10 @@ async function applyAndStart({ serverUrl, enrollKey, deviceName, shell, version,
175
184
  } else {
176
185
  cmdStatus();
177
186
  }
187
+ if (IS_MAC && !noStart && readFdaStatus() !== "granted") {
188
+ console.log("\n⚠ 完全磁盘访问权限尚未授予:PTY 里访问桌面/文稿/下载等目录时,系统弹窗可能因无人点击而卡住。");
189
+ console.log(" 运行 `cofluxd fda` 完成一次性授权(授予后需重启服务生效)。");
190
+ }
178
191
  }
179
192
 
180
193
  // 轮询 ~/.coflux/pending-auth.json(授权链接)与 credentials.json(登记成功)给出全程反馈。
@@ -280,6 +293,11 @@ function cmdStatus() {
280
293
  try { pid = ` (worker pid ${fs.readFileSync(join(HOME, "worker.pid"), "utf8").trim()})`; } catch { /* */ }
281
294
  }
282
295
  console.log(`服务: ${active}${pid}`);
296
+ if (IS_MAC) {
297
+ const fda = readFdaStatus();
298
+ const hint = fda === "granted" ? "" : "(`cofluxd fda` 引导授权,避免弹窗卡住 PTY 会话)";
299
+ console.log(`FDA: ${fdaLabel(fda)}${hint}`);
300
+ }
283
301
  }
284
302
 
285
303
  function cmdLogs(v) {
@@ -291,6 +309,28 @@ function cmdLogs(v) {
291
309
  }
292
310
  }
293
311
 
312
+ // 完全磁盘访问权限(FDA)引导:macOS 不允许程序自动弹出 FDA 授权窗(Apple 刻意设计),
313
+ // 上限就是检测 + 跳转系统设置 + 引导手动添加。授权对象是 supervisor 二进制本身——worker/PTY/agent
314
+ // 都是它的子进程,TCC 按 launchd 服务的 responsible process 归属,一次授权覆盖全树。
315
+ async function cmdFda() {
316
+ if (!IS_MAC) die("此命令仅 macOS 可用(Linux 无 TCC/FDA 概念,无需授权)");
317
+ console.log("\n 完全磁盘访问权限(FDA)引导\n ──────────────────────────\n");
318
+ console.log(" macOS 不支持程序自动弹出 FDA 授权窗,需手动在「系统设置」里添加。");
319
+ console.log(" 请把下面这个二进制拖进「隐私与安全性 → 完全磁盘访问权限」列表并勾选:\n");
320
+ console.log(` ${SUP_BIN}\n`);
321
+ console.log(" 即将打开系统设置面板,并在 Finder 中定位该二进制……\n");
322
+ run("open", ["x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"]);
323
+ run("open", ["-R", SUP_BIN]);
324
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
325
+ try {
326
+ await rl.question(" 添加并勾选后按回车,重启服务使授权生效… ");
327
+ } finally {
328
+ rl.close();
329
+ }
330
+ restartService();
331
+ console.log("\n✓ 已重启服务(FDA 对已运行进程不生效,必须重启才能生效)。稍候用 `cofluxd status` 确认已授予。");
332
+ }
333
+
294
334
  function cmdUninstall(v) {
295
335
  stopService();
296
336
  try { fs.rmSync(IS_MAC ? PLIST : UNIT); } catch { /* */ }
@@ -307,6 +347,7 @@ const HELP = `cofluxd —— coflux daemon 管理
307
347
  cofluxd reload 按 ~/.coflux/settings.json 重载并重启
308
348
  cofluxd update 更新二进制并重启(worker 另可远程热升级)
309
349
  cofluxd status 服务器/登记(含"等待授权")/服务状态
350
+ cofluxd fda [仅 macOS] 引导授予完全磁盘访问权限(避免 PTY 因 TCC 弹窗卡住)
310
351
  cofluxd logs [-f] 看 daemon 日志
311
352
  cofluxd down 停止
312
353
  cofluxd uninstall [--purge] 卸载(--purge 连二进制/配置/凭证一并删)
@@ -335,7 +376,7 @@ let cmd = positionals[0];
335
376
  if (values.help || cmd === "help") { console.log(HELP); process.exit(0); }
336
377
  if (!cmd) cmd = fs.existsSync(SETTINGS) ? "status" : "onboard"; // 首次裸跑 → 引导
337
378
 
338
- const handlers = { up: cmdUp, onboard: cmdOnboard, reload: cmdReload, update: cmdUpdate, down: cmdDown, status: cmdStatus, logs: cmdLogs, uninstall: cmdUninstall };
379
+ const handlers = { up: cmdUp, onboard: cmdOnboard, reload: cmdReload, update: cmdUpdate, down: cmdDown, status: cmdStatus, fda: cmdFda, logs: cmdLogs, uninstall: cmdUninstall };
339
380
  const h = handlers[cmd];
340
381
  if (!h) die(`未知命令: ${cmd}\n\n${HELP}`);
341
382
  await h(values);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cofluxd",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "coflux daemon 管理 CLI:装/起/停/升级 Rust daemon(supervisor + worker)",
5
5
  "type": "module",
6
6
  "bin": {