alink-cli 0.11.11 → 0.11.12

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/dist/ui.js +62 -1
  2. package/package.json +1 -1
package/dist/ui.js CHANGED
@@ -48116,7 +48116,7 @@ var import_react20 = __toESM(require_react(), 1);
48116
48116
  var import_react21 = __toESM(require_react(), 1);
48117
48117
 
48118
48118
  // src/daemonControl.ts
48119
- import { spawn } from "node:child_process";
48119
+ import { spawn, spawnSync } from "node:child_process";
48120
48120
  import {
48121
48121
  chmodSync,
48122
48122
  existsSync as existsSync2,
@@ -48133,6 +48133,13 @@ var STATE_DIR = process.env.AGENTLINK_STATE_DIR || join(homedir(), ".agentlink")
48133
48133
  var CREDENTIAL_FILE = join(STATE_DIR, "credential");
48134
48134
  var PID_FILE = join(STATE_DIR, "daemon.pid");
48135
48135
  var STATUS_FILE = join(STATE_DIR, "status.json");
48136
+ var LAUNCH_AGENT_LABEL = "com.harmopath.agentlink.daemon";
48137
+ var LAUNCH_AGENT_FILE = join(
48138
+ homedir(),
48139
+ "Library",
48140
+ "LaunchAgents",
48141
+ `${LAUNCH_AGENT_LABEL}.plist`
48142
+ );
48136
48143
  var DAEMON_LOCK_FILE = join(
48137
48144
  resolve(process.env.T3CODE_HOME || join(homedir(), ".t3")),
48138
48145
  "userdata",
@@ -48243,10 +48250,58 @@ function daemonPid() {
48243
48250
  function isDaemonRunning() {
48244
48251
  return daemonPid() !== void 0;
48245
48252
  }
48253
+ function xml(value) {
48254
+ return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
48255
+ }
48256
+ function launchAgentDomain() {
48257
+ return `gui/${process.getuid?.() ?? 0}`;
48258
+ }
48259
+ function canUseLaunchAgent() {
48260
+ return process.platform === "darwin" && STATE_DIR === join(homedir(), ".agentlink");
48261
+ }
48262
+ function startLaunchAgent(options) {
48263
+ const cliPath = fileURLToPath(new URL("../bin/agentlink.js", import.meta.url));
48264
+ const args = ["--no-tui", "--hub", normalizeHub(options.hub), "--dir", resolve(options.cwd)];
48265
+ const env3 = [
48266
+ options.approval ? ["AGENTLINK_APPROVAL", "1"] : void 0,
48267
+ options.approvalRenotifyMin !== void 0 ? ["AGENTLINK_APPROVAL_RENOTIFY_MIN", String(options.approvalRenotifyMin)] : void 0
48268
+ ].filter((entry) => Boolean(entry));
48269
+ const environment = env3.length ? `<key>EnvironmentVariables</key><dict>${env3.map(([key, value]) => `<key>${xml(key)}</key><string>${xml(value)}</string>`).join("")}</dict>` : "";
48270
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
48271
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
48272
+ <plist version="1.0"><dict>
48273
+ <key>Label</key><string>${LAUNCH_AGENT_LABEL}</string>
48274
+ <key>ProgramArguments</key><array>${[process.execPath, cliPath, ...args].map((arg) => `<string>${xml(arg)}</string>`).join("")}</array>
48275
+ ${environment}
48276
+ <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
48277
+ <key>StandardOutPath</key><string>${xml(join(STATE_DIR, "daemon.log"))}</string>
48278
+ <key>StandardErrorPath</key><string>${xml(join(STATE_DIR, "daemon.err.log"))}</string>
48279
+ </dict></plist>
48280
+ `;
48281
+ mkdirSync(join(homedir(), "Library", "LaunchAgents"), { recursive: true });
48282
+ writeFileSync(LAUNCH_AGENT_FILE, plist, { mode: 384 });
48283
+ spawnSync("launchctl", ["bootout", `${launchAgentDomain()}/${LAUNCH_AGENT_LABEL}`], {
48284
+ stdio: "ignore"
48285
+ });
48286
+ const result = spawnSync("launchctl", ["bootstrap", launchAgentDomain(), LAUNCH_AGENT_FILE], {
48287
+ encoding: "utf8"
48288
+ });
48289
+ if (result.status !== 0) {
48290
+ throw new Error(result.stderr.trim() || "launchd \u65E0\u6CD5\u542F\u52A8 daemon");
48291
+ }
48292
+ const status = spawnSync("launchctl", ["print", `${launchAgentDomain()}/${LAUNCH_AGENT_LABEL}`], {
48293
+ encoding: "utf8"
48294
+ }).stdout;
48295
+ const pid = Number(status.match(/^\s*pid = (\d+)$/m)?.[1]);
48296
+ if (!pid) throw new Error("launchd \u5DF2\u5B89\u88C5\uFF0C\u4F46 daemon \u5C1A\u672A\u542F\u52A8");
48297
+ writeStatus({ state: "starting", hub: normalizeHub(options.hub), startedAt: Date.now() });
48298
+ return pid;
48299
+ }
48246
48300
  function startDaemon(options) {
48247
48301
  if (isDaemonRunning()) {
48248
48302
  throw new Error("daemon is already running");
48249
48303
  }
48304
+ if (canUseLaunchAgent()) return startLaunchAgent(options);
48250
48305
  const { machineToken, enckey } = parseCredential(options.credential);
48251
48306
  const cwd2 = resolve(options.cwd);
48252
48307
  const daemonPath = options.daemonPath ? resolve(options.daemonPath) : fileURLToPath(new URL("../dist/bin.mjs", import.meta.url));
@@ -48282,6 +48337,12 @@ function startDaemon(options) {
48282
48337
  return child.pid;
48283
48338
  }
48284
48339
  async function stopDaemon(timeoutMs = 1e4) {
48340
+ if (canUseLaunchAgent() && existsSync2(LAUNCH_AGENT_FILE)) {
48341
+ spawnSync("launchctl", ["bootout", `${launchAgentDomain()}/${LAUNCH_AGENT_LABEL}`], {
48342
+ stdio: "ignore"
48343
+ });
48344
+ rmSync(LAUNCH_AGENT_FILE, { force: true });
48345
+ }
48285
48346
  const pid = daemonPid();
48286
48347
  if (!pid) {
48287
48348
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alink-cli",
3
- "version": "0.11.11",
3
+ "version": "0.11.12",
4
4
  "description": "一条命令把工作机接入 AgentLink,随时随地遥控本机的编码 agent。One command to link your machine to AgentLink and control your coding agents from anywhere.",
5
5
  "keywords": [
6
6
  "acp",