xc-copilot-api 1.1.1 → 1.1.3

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.
@@ -5,19 +5,10 @@ import fs from "node:fs";
5
5
  import os from "node:os";
6
6
  import path from "node:path";
7
7
 
8
- //#region src/daemon.ts
8
+ //#region src/daemon/shared.ts
9
9
  const APP_DIR = path.join(os.homedir(), ".local", "share", "copilot-api");
10
10
  const LOG_FILE = path.join(APP_DIR, "copilot-api.log");
11
11
  const ERR_FILE = path.join(APP_DIR, "copilot-api.err");
12
- const LAUNCHD_LABEL = "com.xc-copilot-api";
13
- const SYSTEMD_UNIT = "xc-copilot-api.service";
14
- const WINDOWS_RUN_KEY_NAME = "XcCopilotApi";
15
- function plistPath() {
16
- return path.join(os.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
17
- }
18
- function systemdUnitPath() {
19
- return path.join(os.homedir(), ".config", "systemd", "user", SYSTEMD_UNIT);
20
- }
21
12
  function launcherPath() {
22
13
  return path.join(APP_DIR, "launcher.sh");
23
14
  }
@@ -30,15 +21,43 @@ function buildStartArgs(args) {
30
21
  if (args.proxyEnv) cmd.push("--proxy-env");
31
22
  return cmd;
32
23
  }
24
+ function shellQuote(s) {
25
+ if (/^[\w./:@=-]+$/.test(s)) return s;
26
+ return `'${s.replace(/'/g, "'\\''")}'`;
27
+ }
33
28
  function buildNpxCommand(args) {
34
- return ["npx", ...buildStartArgs(args)].map(shellQuote).join(" ");
29
+ const startArgs = buildStartArgs(args);
30
+ startArgs[0] = "xc-copilot-api@latest";
31
+ return [
32
+ "npx",
33
+ "-y",
34
+ ...startArgs
35
+ ].map(shellQuote).join(" ");
35
36
  }
36
37
  function buildDirectCommand(args) {
37
38
  return buildStartArgs(args).map(shellQuote).join(" ");
38
39
  }
39
- function shellQuote(s) {
40
- if (/^[\w./:@=-]+$/.test(s)) return s;
41
- return `'${s.replace(/'/g, "'\\''")}'`;
40
+ function isMacOS() {
41
+ return process.platform === "darwin";
42
+ }
43
+ function isLinux() {
44
+ return process.platform === "linux";
45
+ }
46
+ function isWindows() {
47
+ return process.platform === "win32";
48
+ }
49
+ function assertSupported() {
50
+ if (!isMacOS() && !isLinux() && !isWindows()) {
51
+ console.error("Daemon management is only supported on macOS, Linux, and Windows.");
52
+ process.exit(1);
53
+ }
54
+ }
55
+
56
+ //#endregion
57
+ //#region src/daemon/macos.ts
58
+ const LAUNCHD_LABEL = "com.xc-copilot-api";
59
+ function plistPath() {
60
+ return path.join(os.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
42
61
  }
43
62
  function installMacOS(args) {
44
63
  const plist = plistPath();
@@ -185,6 +204,35 @@ function statusMacOS() {
185
204
  console.log(` Log: ${LOG_FILE} (${(stat.size / 1024).toFixed(1)} KB)`);
186
205
  }
187
206
  }
207
+ function findAllCopilotLaunchdJobs() {
208
+ const result = spawnSync("launchctl", ["list"], {
209
+ encoding: "utf-8",
210
+ timeout: 5e3
211
+ });
212
+ if (result.status !== 0) return [];
213
+ const jobs = [];
214
+ for (const line of result.stdout.split("\n")) {
215
+ if (!line.toLowerCase().includes("copilot")) continue;
216
+ const parts = line.trim().split(/\s+/);
217
+ if (parts.length < 3) continue;
218
+ const pid = parts[0] === "-" ? null : parts[0];
219
+ const label = parts[2];
220
+ const plist = path.join(os.homedir(), "Library", "LaunchAgents", `${label}.plist`);
221
+ jobs.push({
222
+ label,
223
+ pid,
224
+ plistPath: fs.existsSync(plist) ? plist : null
225
+ });
226
+ }
227
+ return jobs;
228
+ }
229
+
230
+ //#endregion
231
+ //#region src/daemon/linux.ts
232
+ const SYSTEMD_UNIT = "xc-copilot-api.service";
233
+ function systemdUnitPath() {
234
+ return path.join(os.homedir(), ".config", "systemd", "user", SYSTEMD_UNIT);
235
+ }
188
236
  function installLinux(args) {
189
237
  const unitPath = systemdUnitPath();
190
238
  const launcher = launcherPath();
@@ -306,88 +354,116 @@ function statusLinux() {
306
354
  });
307
355
  console.log(result.stdout.trim());
308
356
  }
357
+ function findAllCopilotSystemdUnits() {
358
+ const result = spawnSync("systemctl", [
359
+ "--user",
360
+ "list-units",
361
+ "--all",
362
+ "--no-pager",
363
+ "--plain"
364
+ ], {
365
+ encoding: "utf-8",
366
+ timeout: 5e3
367
+ });
368
+ if (result.status !== 0) return [];
369
+ const units = [];
370
+ for (const line of result.stdout.split("\n")) if (line.toLowerCase().includes("copilot")) {
371
+ const unit = line.trim().split(/\s+/)[0];
372
+ if (unit) units.push(unit);
373
+ }
374
+ return units;
375
+ }
376
+
377
+ //#endregion
378
+ //#region src/daemon/windows.ts
379
+ const WINDOWS_TASK_NAME = "XcCopilotApi";
309
380
  function windowsAppDir() {
310
381
  const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local");
311
382
  return path.join(localAppData, "copilot-api");
312
383
  }
313
- function windowsLauncherVbsPath() {
314
- return path.join(windowsAppDir(), "launcher.vbs");
384
+ function windowsLauncherCmdPath() {
385
+ return path.join(windowsAppDir(), "launcher.cmd");
315
386
  }
316
387
  function windowsLogFile() {
317
388
  return path.join(windowsAppDir(), "copilot-api.log");
318
389
  }
319
390
  function buildWindowsCommand(args) {
320
391
  const startArgs = buildStartArgs(args);
321
- return (args.npx ? ["npx", ...startArgs] : startArgs).map((s) => s.includes(" ") ? `"${s}"` : s).join(" ");
392
+ if (args.npx) {
393
+ startArgs[0] = "xc-copilot-api@latest";
394
+ return [
395
+ "npx",
396
+ "-y",
397
+ ...startArgs
398
+ ].map((s) => s.includes(" ") ? `"${s}"` : s).join(" ");
399
+ }
400
+ return startArgs.map((s) => s.includes(" ") ? `"${s}"` : s).join(" ");
322
401
  }
323
402
  function installWindows(args) {
324
403
  const appDir = windowsAppDir();
325
404
  const logFile = windowsLogFile();
326
405
  const errFile = path.join(appDir, "copilot-api.err");
327
- const launcherVbs = windowsLauncherVbsPath();
406
+ const launcherCmd = windowsLauncherCmdPath();
328
407
  fs.mkdirSync(appDir, { recursive: true });
329
- const execCmd = buildWindowsCommand(args);
330
- const vbsContent = [
331
- "Set WshShell = CreateObject(\"WScript.Shell\")",
332
- `WshShell.Run "${`cmd /c cd /d ""${os.homedir()}"" ^& ${execCmd} >> ""${logFile}"" 2>> ""${errFile}""`}", 0, False`,
408
+ const cmdContent = [
409
+ "@echo off",
410
+ `cd /d "%USERPROFILE%"`,
411
+ `${buildWindowsCommand(args)} >> "${logFile}" 2>> "${errFile}"`,
333
412
  ""
334
413
  ].join("\r\n");
335
- fs.writeFileSync(launcherVbs, vbsContent);
336
- const result = spawnSync("reg.exe", [
337
- "add",
338
- "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
339
- "/v",
340
- WINDOWS_RUN_KEY_NAME,
341
- "/t",
342
- "REG_SZ",
343
- "/d",
344
- `wscript.exe "${launcherVbs}"`,
345
- "/f"
414
+ fs.writeFileSync(launcherCmd, cmdContent);
415
+ const psCmd = [
416
+ `$action = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument '/c "${launcherCmd}"'`,
417
+ `$trigger = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME`,
418
+ `$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero)`,
419
+ `Register-ScheduledTask -TaskName '${WINDOWS_TASK_NAME}' -Action $action -Trigger $trigger -Settings $settings -Force`
420
+ ].join("; ");
421
+ const result = spawnSync("powershell", [
422
+ "-NoProfile",
423
+ "-Command",
424
+ psCmd
346
425
  ], {
347
426
  encoding: "utf-8",
348
- timeout: 1e4
427
+ timeout: 15e3
349
428
  });
350
429
  if (result.status !== 0) {
351
- console.error(`Failed to register Run key: ${(result.stderr || "").trim()}`);
430
+ console.error(`Failed to create scheduled task: ${(result.stderr || "").trim()}`);
352
431
  process.exit(1);
353
432
  }
354
- console.log(`Installed Windows Run key '${WINDOWS_RUN_KEY_NAME}'`);
355
- console.log(` Launcher: ${launcherVbs}`);
433
+ console.log(`Installed scheduled task '${WINDOWS_TASK_NAME}'`);
434
+ console.log(` Launcher: ${launcherCmd}`);
356
435
  console.log(` Log: ${logFile}`);
357
436
  console.log(` Mode: ${args.npx ? "npx (auto-update)" : "direct"}`);
358
437
  console.log(` Start: xc-copilot-api-daemon restart`);
359
438
  }
360
439
  function uninstallWindows() {
361
440
  stopWindows();
362
- spawnSync("reg.exe", [
363
- "delete",
364
- "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
365
- "/v",
366
- WINDOWS_RUN_KEY_NAME,
441
+ spawnSync("schtasks", [
442
+ "/delete",
443
+ "/tn",
444
+ WINDOWS_TASK_NAME,
367
445
  "/f"
368
446
  ], {
369
447
  encoding: "utf-8",
370
448
  timeout: 1e4
371
449
  });
372
- const launcherVbs = windowsLauncherVbsPath();
373
- if (fs.existsSync(launcherVbs)) fs.unlinkSync(launcherVbs);
374
- const legacyCmdPath = path.join(windowsAppDir(), "launcher.cmd");
375
- if (fs.existsSync(legacyCmdPath)) fs.unlinkSync(legacyCmdPath);
376
- console.log(`Uninstalled Windows Run key '${WINDOWS_RUN_KEY_NAME}'`);
450
+ const launcherCmd = windowsLauncherCmdPath();
451
+ if (fs.existsSync(launcherCmd)) fs.unlinkSync(launcherCmd);
452
+ console.log(`Uninstalled scheduled task '${WINDOWS_TASK_NAME}'`);
377
453
  }
378
454
  function startWindows() {
379
- const launcherVbs = windowsLauncherVbsPath();
380
- if (!fs.existsSync(launcherVbs)) {
381
- console.error(`Launcher not found: ${launcherVbs}`);
455
+ if (spawnSync("schtasks", [
456
+ "/run",
457
+ "/tn",
458
+ WINDOWS_TASK_NAME
459
+ ], {
460
+ encoding: "utf-8",
461
+ timeout: 1e4
462
+ }).status !== 0) {
463
+ console.error(`Scheduled task '${WINDOWS_TASK_NAME}' not found.`);
382
464
  console.error("Run 'xc-copilot-api-daemon install' first.");
383
465
  return false;
384
466
  }
385
- spawnSync("wscript.exe", [launcherVbs], {
386
- encoding: "utf-8",
387
- timeout: 1e4,
388
- detached: true,
389
- stdio: "ignore"
390
- });
391
467
  console.log("Started xc-copilot-api (background)");
392
468
  return true;
393
469
  }
@@ -430,23 +506,30 @@ function stopWindows() {
430
506
  return true;
431
507
  }
432
508
  function statusWindows() {
433
- if (spawnSync("reg.exe", [
434
- "query",
435
- "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",
436
- "/v",
437
- WINDOWS_RUN_KEY_NAME
509
+ const taskResult = spawnSync("schtasks", [
510
+ "/query",
511
+ "/tn",
512
+ WINDOWS_TASK_NAME,
513
+ "/fo",
514
+ "LIST"
438
515
  ], {
439
516
  encoding: "utf-8",
440
517
  timeout: 5e3
441
- }).status !== 0) {
518
+ });
519
+ if (taskResult.status !== 0) {
442
520
  console.log("Daemon: not installed");
443
521
  return;
444
522
  }
445
523
  console.log("Daemon: installed");
446
- const launcherVbs = windowsLauncherVbsPath();
447
- if (fs.existsSync(launcherVbs)) {
448
- const match = fs.readFileSync(launcherVbs, "utf-8").match(/\^&\s*(.+?)\s*>>/);
449
- if (match) console.log(` Command: ${match[1].trim()}`);
524
+ const statusMatch = (taskResult.stdout || "").match(/Status:\s*(.+)/i);
525
+ if (statusMatch) console.log(` Task: ${statusMatch[1].trim()}`);
526
+ const launcherCmd = windowsLauncherCmdPath();
527
+ if (fs.existsSync(launcherCmd)) {
528
+ const lines = fs.readFileSync(launcherCmd, "utf-8").split(/\r?\n/).filter((l) => l && !l.startsWith("@") && !l.startsWith("cd "));
529
+ if (lines.length > 0) {
530
+ const cmd = lines[0].replace(/\s*>>.*$/, "").trim();
531
+ if (cmd) console.log(` Command: ${cmd}`);
532
+ }
450
533
  }
451
534
  const pids = findCopilotPids("*copilot-api*start*");
452
535
  console.log(pids.length > 0 ? ` Status: running (PID ${pids.join(", ")})` : " Status: not running");
@@ -456,28 +539,9 @@ function statusWindows() {
456
539
  console.log(` Log: ${logFile} (${(stat.size / 1024).toFixed(1)} KB)`);
457
540
  }
458
541
  }
459
- function findAllCopilotLaunchdJobs() {
460
- const result = spawnSync("launchctl", ["list"], {
461
- encoding: "utf-8",
462
- timeout: 5e3
463
- });
464
- if (result.status !== 0) return [];
465
- const jobs = [];
466
- for (const line of result.stdout.split("\n")) {
467
- if (!line.toLowerCase().includes("copilot")) continue;
468
- const parts = line.trim().split(/\s+/);
469
- if (parts.length < 3) continue;
470
- const pid = parts[0] === "-" ? null : parts[0];
471
- const label = parts[2];
472
- const plist = path.join(os.homedir(), "Library", "LaunchAgents", `${label}.plist`);
473
- jobs.push({
474
- label,
475
- pid,
476
- plistPath: fs.existsSync(plist) ? plist : null
477
- });
478
- }
479
- return jobs;
480
- }
542
+
543
+ //#endregion
544
+ //#region src/daemon/index.ts
481
545
  function findAllCopilotProcesses() {
482
546
  if (isWindows()) {
483
547
  const result = spawnSync("powershell", [
@@ -523,25 +587,6 @@ function findAllCopilotProcesses() {
523
587
  return [];
524
588
  }
525
589
  }
526
- function findAllCopilotSystemdUnits() {
527
- const result = spawnSync("systemctl", [
528
- "--user",
529
- "list-units",
530
- "--all",
531
- "--no-pager",
532
- "--plain"
533
- ], {
534
- encoding: "utf-8",
535
- timeout: 5e3
536
- });
537
- if (result.status !== 0) return [];
538
- const units = [];
539
- for (const line of result.stdout.split("\n")) if (line.toLowerCase().includes("copilot")) {
540
- const unit = line.trim().split(/\s+/)[0];
541
- if (unit) units.push(unit);
542
- }
543
- return units;
544
- }
545
590
  function statusAll() {
546
591
  if (isMacOS()) {
547
592
  const jobs = findAllCopilotLaunchdJobs();
@@ -630,25 +675,10 @@ function stopAll() {
630
675
  if (stopped === 0) console.log("No copilot-api processes found.");
631
676
  else console.log(`\nStopped/killed ${stopped} item(s).`);
632
677
  }
633
- function isMacOS() {
634
- return process.platform === "darwin";
635
- }
636
- function isLinux() {
637
- return process.platform === "linux";
638
- }
639
- function isWindows() {
640
- return process.platform === "win32";
641
- }
642
- function assertSupported() {
643
- if (!isMacOS() && !isLinux() && !isWindows()) {
644
- console.error("Daemon management is only supported on macOS, Linux, and Windows.");
645
- process.exit(1);
646
- }
647
- }
648
678
  const installCmd = defineCommand({
649
679
  meta: {
650
680
  name: "install",
651
- description: "Install xc-copilot-api daemon (launchd on macOS, systemd on Linux, Run key on Windows)"
681
+ description: "Install xc-copilot-api daemon (launchd on macOS, systemd on Linux, Task Scheduler on Windows)"
652
682
  },
653
683
  args: {
654
684
  npx: {
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-main.js","names":["jobs: CopilotJob[]","procs: CopilotProcess[]","units: string[]","installArgs: DaemonInstallArgs"],"sources":["../src/daemon.ts","../src/daemon-main.ts"],"sourcesContent":["/* eslint-disable */\nimport { execSync, spawnSync } from \"node:child_process\"\nimport fs from \"node:fs\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nimport { defineCommand } from \"citty\"\n\nconst APP_DIR = path.join(os.homedir(), \".local\", \"share\", \"copilot-api\")\nconst LOG_FILE = path.join(APP_DIR, \"copilot-api.log\")\nconst ERR_FILE = path.join(APP_DIR, \"copilot-api.err\")\n\n// ---------------------------------------------------------------------------\n// Naming / paths\n// ---------------------------------------------------------------------------\n\nconst LAUNCHD_LABEL = \"com.xc-copilot-api\"\nconst SYSTEMD_UNIT = \"xc-copilot-api.service\"\nconst WINDOWS_RUN_KEY_NAME = \"XcCopilotApi\"\n\nfunction plistPath(): string {\n return path.join(\n os.homedir(),\n \"Library\",\n \"LaunchAgents\",\n `${LAUNCHD_LABEL}.plist`,\n )\n}\n\nfunction systemdUnitPath(): string {\n return path.join(\n os.homedir(),\n \".config\",\n \"systemd\",\n \"user\",\n SYSTEMD_UNIT,\n )\n}\n\nfunction launcherPath(): string {\n return path.join(APP_DIR, \"launcher.sh\")\n}\n\n// ---------------------------------------------------------------------------\n// Build start command\n// ---------------------------------------------------------------------------\n\nfunction buildStartArgs(args: DaemonInstallArgs): string[] {\n const cmd = [\"xc-copilot-api\", \"start\"]\n if (args.port) cmd.push(\"--port\", args.port)\n if (args.verbose) cmd.push(\"--verbose\")\n if (args.accountType && args.accountType !== \"individual\")\n cmd.push(\"--account-type\", args.accountType)\n if (args.githubToken) cmd.push(\"--github-token\", args.githubToken)\n if (args.proxyEnv) cmd.push(\"--proxy-env\")\n return cmd\n}\n\nfunction buildNpxCommand(args: DaemonInstallArgs): string {\n const startArgs = buildStartArgs(args)\n // npx always fetches latest → auto-update on restart\n return [\"npx\", ...startArgs].map(shellQuote).join(\" \")\n}\n\nfunction buildDirectCommand(args: DaemonInstallArgs): string {\n const startArgs = buildStartArgs(args)\n return startArgs.map(shellQuote).join(\" \")\n}\n\nfunction shellQuote(s: string): string {\n if (/^[\\w./:@=-]+$/.test(s)) return s\n return `'${s.replace(/'/g, \"'\\\\''\")}'`\n}\n\n// ---------------------------------------------------------------------------\n// macOS (launchd)\n// ---------------------------------------------------------------------------\n\nfunction installMacOS(args: DaemonInstallArgs): void {\n const plist = plistPath()\n const launcher = launcherPath()\n\n fs.mkdirSync(APP_DIR, { recursive: true })\n fs.mkdirSync(path.dirname(plist), { recursive: true })\n\n const execCmd = args.npx\n ? buildNpxCommand(args)\n : buildDirectCommand(args)\n\n // Launcher script sources login shell so PATH includes nvm, homebrew, etc.\n fs.writeFileSync(\n launcher,\n [\n \"#!/bin/zsh -l\",\n '[ -f \"$HOME/.zshrc\" ] && source \"$HOME/.zshrc\"',\n `exec ${execCmd}`,\n \"\",\n ].join(\"\\n\"),\n )\n fs.chmodSync(launcher, 0o755)\n\n const plistContent = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${LAUNCHD_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${launcher}</string>\n </array>\n <key>WorkingDirectory</key>\n <string>${os.homedir()}</string>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${LOG_FILE}</string>\n <key>StandardErrorPath</key>\n <string>${ERR_FILE}</string>\n</dict>\n</plist>\n`\n fs.writeFileSync(plist, plistContent)\n\n console.log(`Installed LaunchAgent '${LAUNCHD_LABEL}'`)\n console.log(` Plist: ${plist}`)\n console.log(` Launcher: ${launcher}`)\n console.log(` Log: ${LOG_FILE}`)\n console.log(` Mode: ${args.npx ? \"npx (auto-update)\" : \"direct\"}`)\n console.log(` Start: xc-copilot-api-daemon restart`)\n}\n\nfunction uninstallMacOS(): void {\n stopMacOS()\n const plist = plistPath()\n if (fs.existsSync(plist)) {\n fs.unlinkSync(plist)\n console.log(`Removed LaunchAgent plist: ${plist}`)\n }\n const launcher = launcherPath()\n if (fs.existsSync(launcher)) {\n fs.unlinkSync(launcher)\n console.log(`Removed launcher: ${launcher}`)\n }\n console.log(`Uninstalled daemon '${LAUNCHD_LABEL}'`)\n}\n\nfunction stopMacOS(): boolean {\n const domain = `gui/${process.getuid?.() ?? 501}`\n const job = `${domain}/${LAUNCHD_LABEL}`\n const result = spawnSync(\"launchctl\", [\"bootout\", job], {\n encoding: \"utf-8\",\n timeout: 15000,\n })\n if (result.status === 0) {\n console.log(`Stopped LaunchAgent '${LAUNCHD_LABEL}'`)\n return true\n }\n const detail = (result.stderr || result.stdout || \"\").toLowerCase()\n if (detail.includes(\"not find\") || detail.includes(\"no such\")) {\n return true // not running\n }\n return false\n}\n\nfunction startMacOS(): boolean {\n const plist = plistPath()\n if (!fs.existsSync(plist)) {\n console.error(`LaunchAgent plist not found: ${plist}`)\n console.error(\"Run 'xc-copilot-api-daemon install' first.\")\n return false\n }\n\n const domain = `gui/${process.getuid?.() ?? 501}`\n const job = `${domain}/${LAUNCHD_LABEL}`\n\n // Bootstrap (load) the daemon\n const bootstrap = spawnSync(\"launchctl\", [\"bootstrap\", domain, plist], {\n encoding: \"utf-8\",\n timeout: 10000,\n })\n if (bootstrap.status !== 0) {\n const detail = (bootstrap.stderr || bootstrap.stdout || \"\").toLowerCase()\n if (!detail.includes(\"already\")) {\n console.error(`launchctl bootstrap failed: ${detail.trim()}`)\n return false\n }\n }\n\n // Kickstart -k kills existing instance and restarts\n const kick = spawnSync(\"launchctl\", [\"kickstart\", \"-k\", job], {\n encoding: \"utf-8\",\n timeout: 15000,\n })\n if (kick.status !== 0) {\n console.error(\n `launchctl kickstart failed: ${(kick.stderr || kick.stdout || \"\").trim()}`,\n )\n return false\n }\n\n console.log(`Started LaunchAgent '${LAUNCHD_LABEL}'`)\n return true\n}\n\nfunction statusMacOS(): void {\n const plist = plistPath()\n if (!fs.existsSync(plist)) {\n console.log(\"Daemon: not installed\")\n return\n }\n\n console.log(`Daemon: installed`)\n console.log(` Plist: ${plist}`)\n\n const launcher = launcherPath()\n if (fs.existsSync(launcher)) {\n const content = fs.readFileSync(launcher, \"utf-8\")\n const execLine = content\n .split(\"\\n\")\n .find((l) => l.startsWith(\"exec \"))\n if (execLine) {\n console.log(` Command: ${execLine.replace(\"exec \", \"\")}`)\n }\n }\n\n // Check if running via launchctl\n const result = spawnSync(\"launchctl\", [\"list\", LAUNCHD_LABEL], {\n encoding: \"utf-8\",\n timeout: 5000,\n })\n if (result.status === 0) {\n const output = result.stdout.trim()\n // Parse PID and status from launchctl list output\n const pidLine = output\n .split(\"\\n\")\n .find((l) => l.includes(\"PID\") || l.match(/^\\s*\"PID\"/))\n const lastExitLine = output\n .split(\"\\n\")\n .find((l) => l.includes(\"LastExitStatus\"))\n\n // launchctl list <label> outputs key-value pairs\n const pidMatch = output.match(/\"PID\"\\s*=\\s*(\\d+)/)\n const exitMatch = output.match(/\"LastExitStatus\"\\s*=\\s*(\\d+)/)\n\n if (pidMatch) {\n console.log(` Status: running (PID ${pidMatch[1]})`)\n } else {\n console.log(` Status: not running`)\n }\n if (exitMatch) {\n console.log(` Last exit: ${exitMatch[1]}`)\n }\n if (pidLine) void pidLine // suppress unused\n if (lastExitLine) void lastExitLine // suppress unused\n } else {\n console.log(\" Status: not loaded\")\n }\n\n // Show recent log\n if (fs.existsSync(LOG_FILE)) {\n const stat = fs.statSync(LOG_FILE)\n console.log(\n ` Log: ${LOG_FILE} (${(stat.size / 1024).toFixed(1)} KB)`,\n )\n }\n}\n\n// ---------------------------------------------------------------------------\n// Linux (systemd)\n// ---------------------------------------------------------------------------\n\nfunction installLinux(args: DaemonInstallArgs): void {\n const unitPath = systemdUnitPath()\n const launcher = launcherPath()\n\n fs.mkdirSync(APP_DIR, { recursive: true })\n fs.mkdirSync(path.dirname(unitPath), { recursive: true })\n\n const execCmd = args.npx\n ? buildNpxCommand(args)\n : buildDirectCommand(args)\n\n // Launcher script sources login shell\n fs.writeFileSync(\n launcher,\n [\n \"#!/bin/bash -l\",\n '[ -f \"$HOME/.bashrc\" ] && source \"$HOME/.bashrc\"',\n `exec ${execCmd}`,\n \"\",\n ].join(\"\\n\"),\n )\n fs.chmodSync(launcher, 0o755)\n\n const unitContent = `[Unit]\nDescription=xc-copilot-api - GitHub Copilot OpenAI Compatible API\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=${launcher}\nRestart=on-failure\nRestartSec=10\nStandardOutput=append:${LOG_FILE}\nStandardError=append:${ERR_FILE}\n\n[Install]\nWantedBy=default.target\n`\n fs.writeFileSync(unitPath, unitContent)\n\n spawnSync(\"systemctl\", [\"--user\", \"daemon-reload\"], { encoding: \"utf-8\" })\n spawnSync(\"systemctl\", [\"--user\", \"enable\", SYSTEMD_UNIT], {\n encoding: \"utf-8\",\n })\n\n console.log(`Installed systemd unit '${SYSTEMD_UNIT}'`)\n console.log(` Unit: ${unitPath}`)\n console.log(` Launcher: ${launcher}`)\n console.log(` Log: ${LOG_FILE}`)\n console.log(` Mode: ${args.npx ? \"npx (auto-update)\" : \"direct\"}`)\n console.log(` Start: xc-copilot-api-daemon restart`)\n}\n\nfunction uninstallLinux(): void {\n spawnSync(\"systemctl\", [\"--user\", \"stop\", SYSTEMD_UNIT], {\n encoding: \"utf-8\",\n })\n spawnSync(\"systemctl\", [\"--user\", \"disable\", SYSTEMD_UNIT], {\n encoding: \"utf-8\",\n })\n const unitPath = systemdUnitPath()\n if (fs.existsSync(unitPath)) {\n fs.unlinkSync(unitPath)\n spawnSync(\"systemctl\", [\"--user\", \"daemon-reload\"], {\n encoding: \"utf-8\",\n })\n }\n const launcher = launcherPath()\n if (fs.existsSync(launcher)) {\n fs.unlinkSync(launcher)\n }\n console.log(`Uninstalled systemd unit '${SYSTEMD_UNIT}'`)\n}\n\nfunction startLinux(): boolean {\n const result = spawnSync(\n \"systemctl\",\n [\"--user\", \"start\", SYSTEMD_UNIT],\n { encoding: \"utf-8\", timeout: 10000 },\n )\n if (result.status !== 0) {\n console.error(\n `systemd start failed: ${(result.stderr || result.stdout || \"\").trim()}`,\n )\n return false\n }\n console.log(`Started systemd unit '${SYSTEMD_UNIT}'`)\n return true\n}\n\nfunction stopLinux(): boolean {\n const result = spawnSync(\n \"systemctl\",\n [\"--user\", \"stop\", SYSTEMD_UNIT],\n { encoding: \"utf-8\", timeout: 15000 },\n )\n if (result.status !== 0) {\n const detail = (result.stderr || result.stdout || \"\").trim()\n if (!detail.includes(\"not loaded\")) {\n console.error(`systemd stop failed: ${detail}`)\n return false\n }\n }\n console.log(`Stopped systemd unit '${SYSTEMD_UNIT}'`)\n return true\n}\n\nfunction statusLinux(): void {\n const unitPath = systemdUnitPath()\n if (!fs.existsSync(unitPath)) {\n console.log(\"Daemon: not installed\")\n return\n }\n\n console.log(\"Daemon: installed\")\n console.log(` Unit: ${unitPath}`)\n\n const launcher = launcherPath()\n if (fs.existsSync(launcher)) {\n const content = fs.readFileSync(launcher, \"utf-8\")\n const execLine = content\n .split(\"\\n\")\n .find((l) => l.startsWith(\"exec \"))\n if (execLine) {\n console.log(` Command: ${execLine.replace(\"exec \", \"\")}`)\n }\n }\n\n const result = spawnSync(\n \"systemctl\",\n [\"--user\", \"status\", SYSTEMD_UNIT, \"--no-pager\"],\n { encoding: \"utf-8\", timeout: 5000 },\n )\n // systemctl status returns non-zero if daemon is not running, that's ok\n console.log(result.stdout.trim())\n}\n\n// ---------------------------------------------------------------------------\n// Windows (Registry Run Key + VBS launcher)\n// ---------------------------------------------------------------------------\n\nfunction windowsAppDir(): string {\n const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), \"AppData\", \"Local\")\n return path.join(localAppData, \"copilot-api\")\n}\n\nfunction windowsLauncherVbsPath(): string {\n return path.join(windowsAppDir(), \"launcher.vbs\")\n}\n\nfunction windowsLogFile(): string {\n return path.join(windowsAppDir(), \"copilot-api.log\")\n}\n\nfunction buildWindowsCommand(args: DaemonInstallArgs): string {\n const startArgs = buildStartArgs(args)\n const parts = args.npx ? [\"npx\", ...startArgs] : startArgs\n return parts.map((s) => (s.includes(\" \") ? `\"${s}\"` : s)).join(\" \")\n}\n\nfunction installWindows(args: DaemonInstallArgs): void {\n const appDir = windowsAppDir()\n const logFile = windowsLogFile()\n const errFile = path.join(appDir, \"copilot-api.err\")\n const launcherVbs = windowsLauncherVbsPath()\n\n fs.mkdirSync(appDir, { recursive: true })\n\n const execCmd = buildWindowsCommand(args)\n\n // VBS launcher runs command hidden (no console window), with log redirection\n const cmdStr = `cmd /c cd /d \"\"${os.homedir()}\"\" ^& ${execCmd} >> \"\"${logFile}\"\" 2>> \"\"${errFile}\"\"`\n const vbsContent = [\n 'Set WshShell = CreateObject(\"WScript.Shell\")',\n `WshShell.Run \"${cmdStr}\", 0, False`,\n \"\",\n ].join(\"\\r\\n\")\n fs.writeFileSync(launcherVbs, vbsContent)\n\n // Register in current-user Run key (auto-start on login, no admin needed)\n const result = spawnSync(\"reg.exe\", [\n \"add\",\n \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\",\n \"/v\", WINDOWS_RUN_KEY_NAME,\n \"/t\", \"REG_SZ\",\n \"/d\", `wscript.exe \"${launcherVbs}\"`,\n \"/f\",\n ], { encoding: \"utf-8\", timeout: 10000 })\n\n if (result.status !== 0) {\n console.error(`Failed to register Run key: ${(result.stderr || \"\").trim()}`)\n process.exit(1)\n }\n\n console.log(`Installed Windows Run key '${WINDOWS_RUN_KEY_NAME}'`)\n console.log(` Launcher: ${launcherVbs}`)\n console.log(` Log: ${logFile}`)\n console.log(` Mode: ${args.npx ? \"npx (auto-update)\" : \"direct\"}`)\n console.log(` Start: xc-copilot-api-daemon restart`)\n}\n\nfunction uninstallWindows(): void {\n stopWindows()\n\n // Remove Run key\n spawnSync(\"reg.exe\", [\n \"delete\",\n \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\",\n \"/v\", WINDOWS_RUN_KEY_NAME,\n \"/f\",\n ], { encoding: \"utf-8\", timeout: 10000 })\n\n const launcherVbs = windowsLauncherVbsPath()\n if (fs.existsSync(launcherVbs)) fs.unlinkSync(launcherVbs)\n // Clean up legacy CMD launcher if present\n const legacyCmdPath = path.join(windowsAppDir(), \"launcher.cmd\")\n if (fs.existsSync(legacyCmdPath)) fs.unlinkSync(legacyCmdPath)\n console.log(`Uninstalled Windows Run key '${WINDOWS_RUN_KEY_NAME}'`)\n}\n\nfunction startWindows(): boolean {\n const launcherVbs = windowsLauncherVbsPath()\n if (!fs.existsSync(launcherVbs)) {\n console.error(`Launcher not found: ${launcherVbs}`)\n console.error(\"Run 'xc-copilot-api-daemon install' first.\")\n return false\n }\n\n spawnSync(\"wscript.exe\", [launcherVbs], {\n encoding: \"utf-8\",\n timeout: 10000,\n detached: true,\n stdio: \"ignore\",\n })\n\n console.log(\"Started xc-copilot-api (background)\")\n return true\n}\n\nfunction findCopilotPids(filter: string): string[] {\n // Use WQL filter; exclude the PowerShell process itself ($PID) to avoid self-matching\n const wqlFilter = filter.replace(/\\*/g, \"%\")\n const result = spawnSync(\"powershell\", [\n \"-NoProfile\", \"-Command\",\n `Get-CimInstance Win32_Process -Filter \"CommandLine LIKE '${wqlFilter}' AND ProcessId != $PID\" | Select-Object -ExpandProperty ProcessId`,\n ], { encoding: \"utf-8\", timeout: 10000 })\n\n if (result.status !== 0) return []\n return result.stdout.split(\"\\n\").map((l) => l.trim()).filter(Boolean)\n}\n\nfunction stopWindows(): boolean {\n // Find copilot-api processes excluding daemon management and self\n const result = spawnSync(\"powershell\", [\n \"-NoProfile\", \"-Command\",\n `Get-CimInstance Win32_Process -Filter \"CommandLine LIKE '%copilot-api%' AND NOT (CommandLine LIKE '%daemon%') AND ProcessId != $PID\" | Select-Object -ExpandProperty ProcessId`,\n ], { encoding: \"utf-8\", timeout: 10000 })\n\n const pids = (result.status === 0 ? result.stdout : \"\")\n .split(\"\\n\").map((l) => l.trim()).filter(Boolean)\n\n for (const pid of pids) {\n spawnSync(\"taskkill\", [\"/PID\", pid, \"/F\"], { encoding: \"utf-8\", timeout: 5000 })\n }\n\n if (pids.length > 0) {\n console.log(`Stopped ${pids.length} process(es)`)\n return true\n }\n\n console.log(\"No copilot-api processes found.\")\n return true\n}\n\nfunction statusWindows(): void {\n // Check Run key\n const regResult = spawnSync(\"reg.exe\", [\n \"query\",\n \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\",\n \"/v\", WINDOWS_RUN_KEY_NAME,\n ], { encoding: \"utf-8\", timeout: 5000 })\n\n if (regResult.status !== 0) {\n console.log(\"Daemon: not installed\")\n return\n }\n\n console.log(\"Daemon: installed\")\n\n // Show command from VBS launcher\n const launcherVbs = windowsLauncherVbsPath()\n if (fs.existsSync(launcherVbs)) {\n const content = fs.readFileSync(launcherVbs, \"utf-8\")\n // Extract the command between cd /d ... ^& and >> ...\n const match = content.match(/\\^&\\s*(.+?)\\s*>>/)\n if (match) {\n console.log(` Command: ${match[1].trim()}`)\n }\n }\n\n // Check if running\n const pids = findCopilotPids(\"*copilot-api*start*\")\n\n console.log(pids.length > 0\n ? ` Status: running (PID ${pids.join(\", \")})`\n : \" Status: not running\")\n\n const logFile = windowsLogFile()\n if (fs.existsSync(logFile)) {\n const stat = fs.statSync(logFile)\n console.log(` Log: ${logFile} (${(stat.size / 1024).toFixed(1)} KB)`)\n }\n}\n\n// ---------------------------------------------------------------------------\n// --all: find all copilot-api related jobs / processes\n// ---------------------------------------------------------------------------\n\ninterface CopilotJob {\n label: string\n pid: string | null\n plistPath: string | null\n}\n\nfunction findAllCopilotLaunchdJobs(): CopilotJob[] {\n const result = spawnSync(\"launchctl\", [\"list\"], {\n encoding: \"utf-8\",\n timeout: 5000,\n })\n if (result.status !== 0) return []\n\n const jobs: CopilotJob[] = []\n for (const line of result.stdout.split(\"\\n\")) {\n if (!line.toLowerCase().includes(\"copilot\")) continue\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 3) continue\n const pid = parts[0] === \"-\" ? null : parts[0]\n const label = parts[2]\n const plist = path.join(\n os.homedir(),\n \"Library\",\n \"LaunchAgents\",\n `${label}.plist`,\n )\n jobs.push({\n label,\n pid,\n plistPath: fs.existsSync(plist) ? plist : null,\n })\n }\n return jobs\n}\n\ninterface CopilotProcess {\n pid: string\n command: string\n}\n\nfunction findAllCopilotProcesses(): CopilotProcess[] {\n if (isWindows()) {\n const result = spawnSync(\"powershell\", [\n \"-NoProfile\", \"-Command\",\n `Get-CimInstance Win32_Process -Filter \"CommandLine LIKE '%copilot-api%' AND ProcessId != $PID\" | ForEach-Object { \"$($_.ProcessId)|$($_.CommandLine)\" }`,\n ], { encoding: \"utf-8\", timeout: 10000 })\n if (result.status !== 0) return []\n const procs: CopilotProcess[] = []\n for (const line of result.stdout.trim().split(\"\\n\")) {\n if (!line.trim()) continue\n const sep = line.indexOf(\"|\")\n if (sep < 0) continue\n procs.push({ pid: line.slice(0, sep).trim(), command: line.slice(sep + 1).trim() })\n }\n return procs\n }\n\n try {\n const output = execSync(\n \"ps aux | grep -i copilot-api | grep -v grep\",\n { encoding: \"utf-8\", timeout: 5000 },\n )\n const procs: CopilotProcess[] = []\n for (const line of output.trim().split(\"\\n\")) {\n if (!line) continue\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 11) continue\n const pid = parts[1]\n const command = parts.slice(10).join(\" \")\n procs.push({ pid, command })\n }\n return procs\n } catch {\n return []\n }\n}\n\nfunction findAllCopilotSystemdUnits(): string[] {\n const result = spawnSync(\n \"systemctl\",\n [\"--user\", \"list-units\", \"--all\", \"--no-pager\", \"--plain\"],\n { encoding: \"utf-8\", timeout: 5000 },\n )\n if (result.status !== 0) return []\n const units: string[] = []\n for (const line of result.stdout.split(\"\\n\")) {\n if (line.toLowerCase().includes(\"copilot\")) {\n const unit = line.trim().split(/\\s+/)[0]\n if (unit) units.push(unit)\n }\n }\n return units\n}\n\nfunction statusAll(): void {\n if (isMacOS()) {\n const jobs = findAllCopilotLaunchdJobs()\n if (jobs.length > 0) {\n console.log(\"=== LaunchAgent Jobs ===\")\n for (const job of jobs) {\n console.log(`\\n Label: ${job.label}`)\n if (job.plistPath) console.log(` Plist: ${job.plistPath}`)\n else console.log(` Plist: (not found)`)\n console.log(` PID: ${job.pid ?? \"not running\"}`)\n }\n } else {\n console.log(\"No copilot-api LaunchAgent jobs found.\")\n }\n } else if (isWindows()) {\n // Show Run key status\n statusWindows()\n } else {\n const units = findAllCopilotSystemdUnits()\n if (units.length > 0) {\n console.log(\"=== Systemd Units ===\")\n for (const unit of units) {\n const r = spawnSync(\n \"systemctl\",\n [\"--user\", \"status\", unit, \"--no-pager\"],\n { encoding: \"utf-8\", timeout: 5000 },\n )\n console.log(`\\n--- ${unit} ---`)\n console.log(r.stdout.trim())\n }\n } else {\n console.log(\"No copilot-api systemd units found.\")\n }\n }\n\n const procs = findAllCopilotProcesses()\n if (procs.length > 0) {\n console.log(\"\\n=== Processes ===\")\n for (const proc of procs) {\n console.log(` PID ${proc.pid}: ${proc.command}`)\n }\n }\n}\n\nfunction stopAll(): void {\n let stopped = 0\n\n if (isMacOS()) {\n const jobs = findAllCopilotLaunchdJobs()\n const domain = `gui/${process.getuid?.() ?? 501}`\n for (const job of jobs) {\n const jobTarget = `${domain}/${job.label}`\n console.log(`Stopping LaunchAgent '${job.label}'...`)\n spawnSync(\"launchctl\", [\"bootout\", jobTarget], {\n encoding: \"utf-8\",\n timeout: 15000,\n })\n stopped++\n }\n } else if (!isWindows()) {\n const units = findAllCopilotSystemdUnits()\n for (const unit of units) {\n console.log(`Stopping systemd unit '${unit}'...`)\n spawnSync(\"systemctl\", [\"--user\", \"stop\", unit], {\n encoding: \"utf-8\",\n timeout: 15000,\n })\n stopped++\n }\n }\n\n // Kill remaining processes\n const procs = findAllCopilotProcesses()\n for (const proc of procs) {\n console.log(`Killing PID ${proc.pid}: ${proc.command}`)\n if (isWindows()) {\n spawnSync(\"taskkill\", [\"/PID\", proc.pid, \"/F\"], { encoding: \"utf-8\", timeout: 5000 })\n stopped++\n } else {\n try {\n process.kill(Number.parseInt(proc.pid, 10), \"SIGTERM\")\n stopped++\n } catch {\n // already dead\n }\n }\n }\n\n if (stopped === 0) {\n console.log(\"No copilot-api processes found.\")\n } else {\n console.log(`\\nStopped/killed ${stopped} item(s).`)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Platform dispatch\n// ---------------------------------------------------------------------------\n\ninterface DaemonInstallArgs {\n npx: boolean\n port?: string\n verbose: boolean\n accountType?: string\n githubToken?: string\n proxyEnv: boolean\n}\n\nfunction isMacOS(): boolean {\n return process.platform === \"darwin\"\n}\n\nfunction isLinux(): boolean {\n return process.platform === \"linux\"\n}\n\nfunction isWindows(): boolean {\n return process.platform === \"win32\"\n}\n\nfunction assertSupported(): void {\n if (!isMacOS() && !isLinux() && !isWindows()) {\n console.error(\"Daemon management is only supported on macOS, Linux, and Windows.\")\n process.exit(1)\n }\n}\n\n// ---------------------------------------------------------------------------\n// CLI subcommands\n// ---------------------------------------------------------------------------\n\nconst installCmd = defineCommand({\n meta: {\n name: \"install\",\n description:\n \"Install xc-copilot-api daemon (launchd on macOS, systemd on Linux, Run key on Windows)\",\n },\n args: {\n npx: {\n type: \"boolean\",\n default: true,\n description:\n \"Use npx to run (auto-updates on restart). Set --no-npx to use direct binary.\",\n },\n port: {\n alias: \"p\",\n type: \"string\",\n default: \"4141\",\n description: \"Port for the API server\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type (individual, business, enterprise)\",\n },\n \"github-token\": {\n alias: \"g\",\n type: \"string\",\n description: \"GitHub token to use\",\n },\n \"proxy-env\": {\n type: \"boolean\",\n default: false,\n description: \"Initialize proxy from environment variables\",\n },\n },\n run({ args }) {\n assertSupported()\n const installArgs: DaemonInstallArgs = {\n npx: args.npx,\n port: args.port,\n verbose: args.verbose,\n accountType: args[\"account-type\"],\n githubToken: args[\"github-token\"],\n proxyEnv: args[\"proxy-env\"],\n }\n if (isMacOS()) {\n installMacOS(installArgs)\n } else if (isWindows()) {\n installWindows(installArgs)\n } else {\n installLinux(installArgs)\n }\n },\n})\n\nconst uninstallCmd = defineCommand({\n meta: {\n name: \"uninstall\",\n description: \"Uninstall the daemon\",\n },\n run() {\n assertSupported()\n if (isMacOS()) {\n uninstallMacOS()\n } else if (isWindows()) {\n uninstallWindows()\n } else {\n uninstallLinux()\n }\n },\n})\n\nconst statusCmd = defineCommand({\n meta: {\n name: \"status\",\n description: \"Show daemon status (use --all to show all copilot-api instances)\",\n },\n args: {\n all: {\n type: \"boolean\",\n default: false,\n description:\n \"Show all copilot-api related daemons and processes\",\n },\n },\n run({ args }) {\n assertSupported()\n if (args.all) {\n statusAll()\n } else if (isMacOS()) {\n statusMacOS()\n } else if (isWindows()) {\n statusWindows()\n } else {\n statusLinux()\n }\n },\n})\n\nconst restartCmd = defineCommand({\n meta: {\n name: \"restart\",\n description:\n \"Restart the daemon (npx mode fetches latest version automatically)\",\n },\n run() {\n assertSupported()\n if (isMacOS()) {\n if (!startMacOS()) process.exit(1)\n } else if (isWindows()) {\n stopWindows()\n if (!startWindows()) process.exit(1)\n } else {\n stopLinux()\n if (!startLinux()) process.exit(1)\n }\n },\n})\n\nconst stopCmd = defineCommand({\n meta: {\n name: \"stop\",\n description: \"Stop the daemon (use --all to kill all copilot-api instances)\",\n },\n args: {\n all: {\n type: \"boolean\",\n default: false,\n description:\n \"Stop all copilot-api related daemons and kill all processes\",\n },\n },\n run({ args }) {\n assertSupported()\n if (args.all) {\n stopAll()\n } else if (isMacOS()) {\n if (!stopMacOS()) process.exit(1)\n } else if (isWindows()) {\n if (!stopWindows()) process.exit(1)\n } else {\n if (!stopLinux()) process.exit(1)\n }\n },\n})\n\nconst logsCmd = defineCommand({\n meta: {\n name: \"logs\",\n description: \"Show recent daemon logs\",\n },\n args: {\n follow: {\n alias: \"f\",\n type: \"boolean\",\n default: false,\n description: \"Follow log output (like tail -f)\",\n },\n lines: {\n alias: \"n\",\n type: \"string\",\n default: \"50\",\n description: \"Number of lines to show\",\n },\n },\n run({ args }) {\n assertSupported()\n const logPath = isWindows() ? windowsLogFile() : LOG_FILE\n if (!fs.existsSync(logPath)) {\n console.log(\"No log file found.\")\n return\n }\n\n if (isWindows()) {\n // Windows: use powershell Get-Content\n if (args.follow) {\n const { status } = spawnSync(\"powershell\", [\"-Command\", `Get-Content -Path '${logPath}' -Wait -Tail ${args.lines}`], { stdio: \"inherit\" })\n process.exit(status ?? 0)\n } else {\n const { status } = spawnSync(\"powershell\", [\"-Command\", `Get-Content -Path '${logPath}' -Tail ${args.lines}`], { stdio: \"inherit\" })\n process.exit(status ?? 0)\n }\n } else {\n if (args.follow) {\n const { status } = spawnSync(\"tail\", [\"-f\", logPath], { stdio: \"inherit\" })\n process.exit(status ?? 0)\n } else {\n const { status } = spawnSync(\"tail\", [\"-n\", args.lines, logPath], { stdio: \"inherit\" })\n process.exit(status ?? 0)\n }\n }\n },\n})\n\n// ---------------------------------------------------------------------------\n// Main daemon command\n// ---------------------------------------------------------------------------\n\nexport const daemon = defineCommand({\n meta: {\n name: \"xc-copilot-api-daemon\",\n description:\n \"Manage xc-copilot-api daemon (install, status, restart, stop, uninstall, logs)\",\n },\n subCommands: {\n install: installCmd,\n uninstall: uninstallCmd,\n status: statusCmd,\n restart: restartCmd,\n stop: stopCmd,\n logs: logsCmd,\n },\n})\n","#!/usr/bin/env node\n\nimport { runMain } from \"citty\"\n\nimport { daemon } from \"./daemon\"\n\nawait runMain(daemon)\n"],"mappings":"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"}
1
+ {"version":3,"file":"daemon-main.js","names":["jobs: CopilotJob[]","units: string[]","procs: CopilotProcess[]","installArgs: DaemonInstallArgs"],"sources":["../src/daemon/shared.ts","../src/daemon/macos.ts","../src/daemon/linux.ts","../src/daemon/windows.ts","../src/daemon/index.ts","../src/daemon-main.ts"],"sourcesContent":["/* eslint-disable */\r\nimport os from \"node:os\"\r\nimport path from \"node:path\"\r\n\r\nexport const APP_DIR = path.join(os.homedir(), \".local\", \"share\", \"copilot-api\")\r\nexport const LOG_FILE = path.join(APP_DIR, \"copilot-api.log\")\r\nexport const ERR_FILE = path.join(APP_DIR, \"copilot-api.err\")\r\n\r\nexport interface DaemonInstallArgs {\r\n npx: boolean\r\n port?: string\r\n verbose: boolean\r\n accountType?: string\r\n githubToken?: string\r\n proxyEnv: boolean\r\n}\r\n\r\nexport interface CopilotProcess {\r\n pid: string\r\n command: string\r\n}\r\n\r\nexport function launcherPath(): string {\r\n return path.join(APP_DIR, \"launcher.sh\")\r\n}\r\n\r\nexport function buildStartArgs(args: DaemonInstallArgs): string[] {\r\n const cmd = [\"xc-copilot-api\", \"start\"]\r\n if (args.port) cmd.push(\"--port\", args.port)\r\n if (args.verbose) cmd.push(\"--verbose\")\r\n if (args.accountType && args.accountType !== \"individual\")\r\n cmd.push(\"--account-type\", args.accountType)\r\n if (args.githubToken) cmd.push(\"--github-token\", args.githubToken)\r\n if (args.proxyEnv) cmd.push(\"--proxy-env\")\r\n return cmd\r\n}\r\n\r\nexport function shellQuote(s: string): string {\r\n if (/^[\\w./:@=-]+$/.test(s)) return s\r\n return `'${s.replace(/'/g, \"'\\\\''\")}'`\r\n}\r\n\r\nexport function buildNpxCommand(args: DaemonInstallArgs): string {\r\n const startArgs = buildStartArgs(args)\r\n // -y skips install prompt; @latest ensures fresh version on every run\r\n startArgs[0] = \"xc-copilot-api@latest\"\r\n return [\"npx\", \"-y\", ...startArgs].map(shellQuote).join(\" \")\r\n}\r\n\r\nexport function buildDirectCommand(args: DaemonInstallArgs): string {\r\n const startArgs = buildStartArgs(args)\r\n return startArgs.map(shellQuote).join(\" \")\r\n}\r\n\r\nexport function isMacOS(): boolean {\r\n return process.platform === \"darwin\"\r\n}\r\n\r\nexport function isLinux(): boolean {\r\n return process.platform === \"linux\"\r\n}\r\n\r\nexport function isWindows(): boolean {\r\n return process.platform === \"win32\"\r\n}\r\n\r\nexport function assertSupported(): void {\r\n if (!isMacOS() && !isLinux() && !isWindows()) {\r\n console.error(\"Daemon management is only supported on macOS, Linux, and Windows.\")\r\n process.exit(1)\r\n }\r\n}\r\n","/* eslint-disable */\r\nimport { spawnSync } from \"node:child_process\"\r\nimport fs from \"node:fs\"\r\nimport os from \"node:os\"\r\nimport path from \"node:path\"\r\n\r\nimport {\r\n APP_DIR,\r\n ERR_FILE,\r\n LOG_FILE,\r\n buildDirectCommand,\r\n buildNpxCommand,\r\n launcherPath,\r\n} from \"./shared\"\r\nimport type { DaemonInstallArgs } from \"./shared\"\r\n\r\nconst LAUNCHD_LABEL = \"com.xc-copilot-api\"\r\n\r\nfunction plistPath(): string {\r\n return path.join(\r\n os.homedir(),\r\n \"Library\",\r\n \"LaunchAgents\",\r\n `${LAUNCHD_LABEL}.plist`,\r\n )\r\n}\r\n\r\nexport function installMacOS(args: DaemonInstallArgs): void {\r\n const plist = plistPath()\r\n const launcher = launcherPath()\r\n\r\n fs.mkdirSync(APP_DIR, { recursive: true })\r\n fs.mkdirSync(path.dirname(plist), { recursive: true })\r\n\r\n const execCmd = args.npx\r\n ? buildNpxCommand(args)\r\n : buildDirectCommand(args)\r\n\r\n // Launcher script sources login shell so PATH includes nvm, homebrew, etc.\r\n fs.writeFileSync(\r\n launcher,\r\n [\r\n \"#!/bin/zsh -l\",\r\n '[ -f \"$HOME/.zshrc\" ] && source \"$HOME/.zshrc\"',\r\n `exec ${execCmd}`,\r\n \"\",\r\n ].join(\"\\n\"),\r\n )\r\n fs.chmodSync(launcher, 0o755)\r\n\r\n const plistContent = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n<plist version=\"1.0\">\r\n<dict>\r\n <key>Label</key>\r\n <string>${LAUNCHD_LABEL}</string>\r\n <key>ProgramArguments</key>\r\n <array>\r\n <string>${launcher}</string>\r\n </array>\r\n <key>WorkingDirectory</key>\r\n <string>${os.homedir()}</string>\r\n <key>RunAtLoad</key>\r\n <true/>\r\n <key>KeepAlive</key>\r\n <true/>\r\n <key>StandardOutPath</key>\r\n <string>${LOG_FILE}</string>\r\n <key>StandardErrorPath</key>\r\n <string>${ERR_FILE}</string>\r\n</dict>\r\n</plist>\r\n`\r\n fs.writeFileSync(plist, plistContent)\r\n\r\n console.log(`Installed LaunchAgent '${LAUNCHD_LABEL}'`)\r\n console.log(` Plist: ${plist}`)\r\n console.log(` Launcher: ${launcher}`)\r\n console.log(` Log: ${LOG_FILE}`)\r\n console.log(` Mode: ${args.npx ? \"npx (auto-update)\" : \"direct\"}`)\r\n console.log(` Start: xc-copilot-api-daemon restart`)\r\n}\r\n\r\nexport function uninstallMacOS(): void {\r\n stopMacOS()\r\n const plist = plistPath()\r\n if (fs.existsSync(plist)) {\r\n fs.unlinkSync(plist)\r\n console.log(`Removed LaunchAgent plist: ${plist}`)\r\n }\r\n const launcher = launcherPath()\r\n if (fs.existsSync(launcher)) {\r\n fs.unlinkSync(launcher)\r\n console.log(`Removed launcher: ${launcher}`)\r\n }\r\n console.log(`Uninstalled daemon '${LAUNCHD_LABEL}'`)\r\n}\r\n\r\nexport function stopMacOS(): boolean {\r\n const domain = `gui/${process.getuid?.() ?? 501}`\r\n const job = `${domain}/${LAUNCHD_LABEL}`\r\n const result = spawnSync(\"launchctl\", [\"bootout\", job], {\r\n encoding: \"utf-8\",\r\n timeout: 15000,\r\n })\r\n if (result.status === 0) {\r\n console.log(`Stopped LaunchAgent '${LAUNCHD_LABEL}'`)\r\n return true\r\n }\r\n const detail = (result.stderr || result.stdout || \"\").toLowerCase()\r\n if (detail.includes(\"not find\") || detail.includes(\"no such\")) {\r\n return true // not running\r\n }\r\n return false\r\n}\r\n\r\nexport function startMacOS(): boolean {\r\n const plist = plistPath()\r\n if (!fs.existsSync(plist)) {\r\n console.error(`LaunchAgent plist not found: ${plist}`)\r\n console.error(\"Run 'xc-copilot-api-daemon install' first.\")\r\n return false\r\n }\r\n\r\n const domain = `gui/${process.getuid?.() ?? 501}`\r\n const job = `${domain}/${LAUNCHD_LABEL}`\r\n\r\n // Bootstrap (load) the daemon\r\n const bootstrap = spawnSync(\"launchctl\", [\"bootstrap\", domain, plist], {\r\n encoding: \"utf-8\",\r\n timeout: 10000,\r\n })\r\n if (bootstrap.status !== 0) {\r\n const detail = (bootstrap.stderr || bootstrap.stdout || \"\").toLowerCase()\r\n if (!detail.includes(\"already\")) {\r\n console.error(`launchctl bootstrap failed: ${detail.trim()}`)\r\n return false\r\n }\r\n }\r\n\r\n // Kickstart -k kills existing instance and restarts\r\n const kick = spawnSync(\"launchctl\", [\"kickstart\", \"-k\", job], {\r\n encoding: \"utf-8\",\r\n timeout: 15000,\r\n })\r\n if (kick.status !== 0) {\r\n console.error(\r\n `launchctl kickstart failed: ${(kick.stderr || kick.stdout || \"\").trim()}`,\r\n )\r\n return false\r\n }\r\n\r\n console.log(`Started LaunchAgent '${LAUNCHD_LABEL}'`)\r\n return true\r\n}\r\n\r\nexport function statusMacOS(): void {\r\n const plist = plistPath()\r\n if (!fs.existsSync(plist)) {\r\n console.log(\"Daemon: not installed\")\r\n return\r\n }\r\n\r\n console.log(`Daemon: installed`)\r\n console.log(` Plist: ${plist}`)\r\n\r\n const launcher = launcherPath()\r\n if (fs.existsSync(launcher)) {\r\n const content = fs.readFileSync(launcher, \"utf-8\")\r\n const execLine = content\r\n .split(\"\\n\")\r\n .find((l) => l.startsWith(\"exec \"))\r\n if (execLine) {\r\n console.log(` Command: ${execLine.replace(\"exec \", \"\")}`)\r\n }\r\n }\r\n\r\n // Check if running via launchctl\r\n const result = spawnSync(\"launchctl\", [\"list\", LAUNCHD_LABEL], {\r\n encoding: \"utf-8\",\r\n timeout: 5000,\r\n })\r\n if (result.status === 0) {\r\n const output = result.stdout.trim()\r\n // Parse PID and status from launchctl list output\r\n const pidLine = output\r\n .split(\"\\n\")\r\n .find((l) => l.includes(\"PID\") || l.match(/^\\s*\"PID\"/))\r\n const lastExitLine = output\r\n .split(\"\\n\")\r\n .find((l) => l.includes(\"LastExitStatus\"))\r\n\r\n // launchctl list <label> outputs key-value pairs\r\n const pidMatch = output.match(/\"PID\"\\s*=\\s*(\\d+)/)\r\n const exitMatch = output.match(/\"LastExitStatus\"\\s*=\\s*(\\d+)/)\r\n\r\n if (pidMatch) {\r\n console.log(` Status: running (PID ${pidMatch[1]})`)\r\n } else {\r\n console.log(` Status: not running`)\r\n }\r\n if (exitMatch) {\r\n console.log(` Last exit: ${exitMatch[1]}`)\r\n }\r\n if (pidLine) void pidLine // suppress unused\r\n if (lastExitLine) void lastExitLine // suppress unused\r\n } else {\r\n console.log(\" Status: not loaded\")\r\n }\r\n\r\n // Show recent log\r\n if (fs.existsSync(LOG_FILE)) {\r\n const stat = fs.statSync(LOG_FILE)\r\n console.log(\r\n ` Log: ${LOG_FILE} (${(stat.size / 1024).toFixed(1)} KB)`,\r\n )\r\n }\r\n}\r\n\r\nexport interface CopilotJob {\r\n label: string\r\n pid: string | null\r\n plistPath: string | null\r\n}\r\n\r\nexport function findAllCopilotLaunchdJobs(): CopilotJob[] {\r\n const result = spawnSync(\"launchctl\", [\"list\"], {\r\n encoding: \"utf-8\",\r\n timeout: 5000,\r\n })\r\n if (result.status !== 0) return []\r\n\r\n const jobs: CopilotJob[] = []\r\n for (const line of result.stdout.split(\"\\n\")) {\r\n if (!line.toLowerCase().includes(\"copilot\")) continue\r\n const parts = line.trim().split(/\\s+/)\r\n if (parts.length < 3) continue\r\n const pid = parts[0] === \"-\" ? null : parts[0]\r\n const label = parts[2]\r\n const plist = path.join(\r\n os.homedir(),\r\n \"Library\",\r\n \"LaunchAgents\",\r\n `${label}.plist`,\r\n )\r\n jobs.push({\r\n label,\r\n pid,\r\n plistPath: fs.existsSync(plist) ? plist : null,\r\n })\r\n }\r\n return jobs\r\n}\r\n","/* eslint-disable */\r\nimport { spawnSync } from \"node:child_process\"\r\nimport fs from \"node:fs\"\r\nimport os from \"node:os\"\r\nimport path from \"node:path\"\r\n\r\nimport {\r\n APP_DIR,\r\n ERR_FILE,\r\n LOG_FILE,\r\n buildDirectCommand,\r\n buildNpxCommand,\r\n launcherPath,\r\n} from \"./shared\"\r\nimport type { DaemonInstallArgs } from \"./shared\"\r\n\r\nconst SYSTEMD_UNIT = \"xc-copilot-api.service\"\r\n\r\nfunction systemdUnitPath(): string {\r\n return path.join(\r\n os.homedir(),\r\n \".config\",\r\n \"systemd\",\r\n \"user\",\r\n SYSTEMD_UNIT,\r\n )\r\n}\r\n\r\nexport function installLinux(args: DaemonInstallArgs): void {\r\n const unitPath = systemdUnitPath()\r\n const launcher = launcherPath()\r\n\r\n fs.mkdirSync(APP_DIR, { recursive: true })\r\n fs.mkdirSync(path.dirname(unitPath), { recursive: true })\r\n\r\n const execCmd = args.npx\r\n ? buildNpxCommand(args)\r\n : buildDirectCommand(args)\r\n\r\n // Launcher script sources login shell\r\n fs.writeFileSync(\r\n launcher,\r\n [\r\n \"#!/bin/bash -l\",\r\n '[ -f \"$HOME/.bashrc\" ] && source \"$HOME/.bashrc\"',\r\n `exec ${execCmd}`,\r\n \"\",\r\n ].join(\"\\n\"),\r\n )\r\n fs.chmodSync(launcher, 0o755)\r\n\r\n const unitContent = `[Unit]\r\nDescription=xc-copilot-api - GitHub Copilot OpenAI Compatible API\r\nAfter=network.target\r\n\r\n[Service]\r\nType=simple\r\nExecStart=${launcher}\r\nRestart=on-failure\r\nRestartSec=10\r\nStandardOutput=append:${LOG_FILE}\r\nStandardError=append:${ERR_FILE}\r\n\r\n[Install]\r\nWantedBy=default.target\r\n`\r\n fs.writeFileSync(unitPath, unitContent)\r\n\r\n spawnSync(\"systemctl\", [\"--user\", \"daemon-reload\"], { encoding: \"utf-8\" })\r\n spawnSync(\"systemctl\", [\"--user\", \"enable\", SYSTEMD_UNIT], {\r\n encoding: \"utf-8\",\r\n })\r\n\r\n console.log(`Installed systemd unit '${SYSTEMD_UNIT}'`)\r\n console.log(` Unit: ${unitPath}`)\r\n console.log(` Launcher: ${launcher}`)\r\n console.log(` Log: ${LOG_FILE}`)\r\n console.log(` Mode: ${args.npx ? \"npx (auto-update)\" : \"direct\"}`)\r\n console.log(` Start: xc-copilot-api-daemon restart`)\r\n}\r\n\r\nexport function uninstallLinux(): void {\r\n spawnSync(\"systemctl\", [\"--user\", \"stop\", SYSTEMD_UNIT], {\r\n encoding: \"utf-8\",\r\n })\r\n spawnSync(\"systemctl\", [\"--user\", \"disable\", SYSTEMD_UNIT], {\r\n encoding: \"utf-8\",\r\n })\r\n const unitPath = systemdUnitPath()\r\n if (fs.existsSync(unitPath)) {\r\n fs.unlinkSync(unitPath)\r\n spawnSync(\"systemctl\", [\"--user\", \"daemon-reload\"], {\r\n encoding: \"utf-8\",\r\n })\r\n }\r\n const launcher = launcherPath()\r\n if (fs.existsSync(launcher)) {\r\n fs.unlinkSync(launcher)\r\n }\r\n console.log(`Uninstalled systemd unit '${SYSTEMD_UNIT}'`)\r\n}\r\n\r\nexport function startLinux(): boolean {\r\n const result = spawnSync(\r\n \"systemctl\",\r\n [\"--user\", \"start\", SYSTEMD_UNIT],\r\n { encoding: \"utf-8\", timeout: 10000 },\r\n )\r\n if (result.status !== 0) {\r\n console.error(\r\n `systemd start failed: ${(result.stderr || result.stdout || \"\").trim()}`,\r\n )\r\n return false\r\n }\r\n console.log(`Started systemd unit '${SYSTEMD_UNIT}'`)\r\n return true\r\n}\r\n\r\nexport function stopLinux(): boolean {\r\n const result = spawnSync(\r\n \"systemctl\",\r\n [\"--user\", \"stop\", SYSTEMD_UNIT],\r\n { encoding: \"utf-8\", timeout: 15000 },\r\n )\r\n if (result.status !== 0) {\r\n const detail = (result.stderr || result.stdout || \"\").trim()\r\n if (!detail.includes(\"not loaded\")) {\r\n console.error(`systemd stop failed: ${detail}`)\r\n return false\r\n }\r\n }\r\n console.log(`Stopped systemd unit '${SYSTEMD_UNIT}'`)\r\n return true\r\n}\r\n\r\nexport function statusLinux(): void {\r\n const unitPath = systemdUnitPath()\r\n if (!fs.existsSync(unitPath)) {\r\n console.log(\"Daemon: not installed\")\r\n return\r\n }\r\n\r\n console.log(\"Daemon: installed\")\r\n console.log(` Unit: ${unitPath}`)\r\n\r\n const launcher = launcherPath()\r\n if (fs.existsSync(launcher)) {\r\n const content = fs.readFileSync(launcher, \"utf-8\")\r\n const execLine = content\r\n .split(\"\\n\")\r\n .find((l) => l.startsWith(\"exec \"))\r\n if (execLine) {\r\n console.log(` Command: ${execLine.replace(\"exec \", \"\")}`)\r\n }\r\n }\r\n\r\n const result = spawnSync(\r\n \"systemctl\",\r\n [\"--user\", \"status\", SYSTEMD_UNIT, \"--no-pager\"],\r\n { encoding: \"utf-8\", timeout: 5000 },\r\n )\r\n // systemctl status returns non-zero if daemon is not running, that's ok\r\n console.log(result.stdout.trim())\r\n}\r\n\r\nexport function findAllCopilotSystemdUnits(): string[] {\r\n const result = spawnSync(\r\n \"systemctl\",\r\n [\"--user\", \"list-units\", \"--all\", \"--no-pager\", \"--plain\"],\r\n { encoding: \"utf-8\", timeout: 5000 },\r\n )\r\n if (result.status !== 0) return []\r\n const units: string[] = []\r\n for (const line of result.stdout.split(\"\\n\")) {\r\n if (line.toLowerCase().includes(\"copilot\")) {\r\n const unit = line.trim().split(/\\s+/)[0]\r\n if (unit) units.push(unit)\r\n }\r\n }\r\n return units\r\n}\r\n","/* eslint-disable */\r\nimport { spawnSync } from \"node:child_process\"\r\nimport fs from \"node:fs\"\r\nimport os from \"node:os\"\r\nimport path from \"node:path\"\r\n\r\nimport { buildStartArgs } from \"./shared\"\r\nimport type { DaemonInstallArgs } from \"./shared\"\r\n\r\nconst WINDOWS_TASK_NAME = \"XcCopilotApi\"\r\n\r\nfunction windowsAppDir(): string {\r\n const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), \"AppData\", \"Local\")\r\n return path.join(localAppData, \"copilot-api\")\r\n}\r\n\r\nfunction windowsLauncherCmdPath(): string {\r\n return path.join(windowsAppDir(), \"launcher.cmd\")\r\n}\r\n\r\nexport function windowsLogFile(): string {\r\n return path.join(windowsAppDir(), \"copilot-api.log\")\r\n}\r\n\r\nfunction buildWindowsCommand(args: DaemonInstallArgs): string {\r\n const startArgs = buildStartArgs(args)\r\n if (args.npx) {\r\n startArgs[0] = \"xc-copilot-api@latest\"\r\n const parts = [\"npx\", \"-y\", ...startArgs]\r\n return parts.map((s) => (s.includes(\" \") ? `\"${s}\"` : s)).join(\" \")\r\n }\r\n return startArgs.map((s) => (s.includes(\" \") ? `\"${s}\"` : s)).join(\" \")\r\n}\r\n\r\nexport function installWindows(args: DaemonInstallArgs): void {\r\n const appDir = windowsAppDir()\r\n const logFile = windowsLogFile()\r\n const errFile = path.join(appDir, \"copilot-api.err\")\r\n const launcherCmd = windowsLauncherCmdPath()\r\n\r\n fs.mkdirSync(appDir, { recursive: true })\r\n\r\n const execCmd = buildWindowsCommand(args)\r\n\r\n // CMD launcher script with log redirection\r\n const cmdContent = [\r\n \"@echo off\",\r\n `cd /d \"%USERPROFILE%\"`,\r\n `${execCmd} >> \"${logFile}\" 2>> \"${errFile}\"`,\r\n \"\",\r\n ].join(\"\\r\\n\")\r\n fs.writeFileSync(launcherCmd, cmdContent)\r\n\r\n // Register as a scheduled task (on-logon trigger, no admin needed)\r\n const psCmd = [\r\n `$action = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument '/c \"${launcherCmd}\"'`,\r\n `$trigger = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME`,\r\n `$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit ([TimeSpan]::Zero)`,\r\n `Register-ScheduledTask -TaskName '${WINDOWS_TASK_NAME}' -Action $action -Trigger $trigger -Settings $settings -Force`,\r\n ].join(\"; \")\r\n const result = spawnSync(\"powershell\", [\r\n \"-NoProfile\", \"-Command\", psCmd,\r\n ], { encoding: \"utf-8\", timeout: 15000 })\r\n\r\n if (result.status !== 0) {\r\n console.error(`Failed to create scheduled task: ${(result.stderr || \"\").trim()}`)\r\n process.exit(1)\r\n }\r\n\r\n console.log(`Installed scheduled task '${WINDOWS_TASK_NAME}'`)\r\n console.log(` Launcher: ${launcherCmd}`)\r\n console.log(` Log: ${logFile}`)\r\n console.log(` Mode: ${args.npx ? \"npx (auto-update)\" : \"direct\"}`)\r\n console.log(` Start: xc-copilot-api-daemon restart`)\r\n}\r\n\r\nexport function uninstallWindows(): void {\r\n stopWindows()\r\n\r\n // Remove scheduled task\r\n spawnSync(\"schtasks\", [\r\n \"/delete\",\r\n \"/tn\", WINDOWS_TASK_NAME,\r\n \"/f\",\r\n ], { encoding: \"utf-8\", timeout: 10000 })\r\n\r\n const launcherCmd = windowsLauncherCmdPath()\r\n if (fs.existsSync(launcherCmd)) fs.unlinkSync(launcherCmd)\r\n\r\n console.log(`Uninstalled scheduled task '${WINDOWS_TASK_NAME}'`)\r\n}\r\n\r\nexport function startWindows(): boolean {\r\n const result = spawnSync(\"schtasks\", [\r\n \"/run\",\r\n \"/tn\", WINDOWS_TASK_NAME,\r\n ], { encoding: \"utf-8\", timeout: 10000 })\r\n\r\n if (result.status !== 0) {\r\n console.error(`Scheduled task '${WINDOWS_TASK_NAME}' not found.`)\r\n console.error(\"Run 'xc-copilot-api-daemon install' first.\")\r\n return false\r\n }\r\n\r\n console.log(\"Started xc-copilot-api (background)\")\r\n return true\r\n}\r\n\r\nexport function findCopilotPids(filter: string): string[] {\r\n // Use WQL filter; exclude the PowerShell process itself ($PID) to avoid self-matching\r\n const wqlFilter = filter.replace(/\\*/g, \"%\")\r\n const result = spawnSync(\"powershell\", [\r\n \"-NoProfile\", \"-Command\",\r\n `Get-CimInstance Win32_Process -Filter \"CommandLine LIKE '${wqlFilter}' AND ProcessId != $PID\" | Select-Object -ExpandProperty ProcessId`,\r\n ], { encoding: \"utf-8\", timeout: 10000 })\r\n\r\n if (result.status !== 0) return []\r\n return result.stdout.split(\"\\n\").map((l) => l.trim()).filter(Boolean)\r\n}\r\n\r\nexport function stopWindows(): boolean {\r\n // Find copilot-api processes excluding daemon management and self\r\n const result = spawnSync(\"powershell\", [\r\n \"-NoProfile\", \"-Command\",\r\n `Get-CimInstance Win32_Process -Filter \"CommandLine LIKE '%copilot-api%' AND NOT (CommandLine LIKE '%daemon%') AND ProcessId != $PID\" | Select-Object -ExpandProperty ProcessId`,\r\n ], { encoding: \"utf-8\", timeout: 10000 })\r\n\r\n const pids = (result.status === 0 ? result.stdout : \"\")\r\n .split(\"\\n\").map((l) => l.trim()).filter(Boolean)\r\n\r\n for (const pid of pids) {\r\n spawnSync(\"taskkill\", [\"/PID\", pid, \"/F\"], { encoding: \"utf-8\", timeout: 5000 })\r\n }\r\n\r\n if (pids.length > 0) {\r\n console.log(`Stopped ${pids.length} process(es)`)\r\n return true\r\n }\r\n\r\n console.log(\"No copilot-api processes found.\")\r\n return true\r\n}\r\n\r\nexport function statusWindows(): void {\r\n // Check scheduled task\r\n const taskResult = spawnSync(\"schtasks\", [\r\n \"/query\",\r\n \"/tn\", WINDOWS_TASK_NAME,\r\n \"/fo\", \"LIST\",\r\n ], { encoding: \"utf-8\", timeout: 5000 })\r\n\r\n if (taskResult.status !== 0) {\r\n console.log(\"Daemon: not installed\")\r\n return\r\n }\r\n\r\n console.log(\"Daemon: installed\")\r\n\r\n // Parse task status from schtasks output\r\n const statusMatch = (taskResult.stdout || \"\").match(/Status:\\s*(.+)/i)\r\n if (statusMatch) {\r\n console.log(` Task: ${statusMatch[1].trim()}`)\r\n }\r\n\r\n // Show command from CMD launcher\r\n const launcherCmd = windowsLauncherCmdPath()\r\n if (fs.existsSync(launcherCmd)) {\r\n const content = fs.readFileSync(launcherCmd, \"utf-8\")\r\n const lines = content.split(/\\r?\\n/).filter((l) => l && !l.startsWith(\"@\") && !l.startsWith(\"cd \"))\r\n if (lines.length > 0) {\r\n // Strip log redirection to show just the command\r\n const cmd = lines[0].replace(/\\s*>>.*$/, \"\").trim()\r\n if (cmd) console.log(` Command: ${cmd}`)\r\n }\r\n }\r\n\r\n // Check if running\r\n const pids = findCopilotPids(\"*copilot-api*start*\")\r\n\r\n console.log(pids.length > 0\r\n ? ` Status: running (PID ${pids.join(\", \")})`\r\n : \" Status: not running\")\r\n\r\n const logFile = windowsLogFile()\r\n if (fs.existsSync(logFile)) {\r\n const stat = fs.statSync(logFile)\r\n console.log(` Log: ${logFile} (${(stat.size / 1024).toFixed(1)} KB)`)\r\n }\r\n}\r\n","/* eslint-disable */\r\nimport { execSync, spawnSync } from \"node:child_process\"\r\nimport fs from \"node:fs\"\r\n\r\nimport { defineCommand } from \"citty\"\r\n\r\nimport { findAllCopilotLaunchdJobs } from \"./macos\"\r\nimport { installMacOS, startMacOS, statusMacOS, stopMacOS, uninstallMacOS } from \"./macos\"\r\nimport { findAllCopilotSystemdUnits } from \"./linux\"\r\nimport { installLinux, startLinux, statusLinux, stopLinux, uninstallLinux } from \"./linux\"\r\nimport { installWindows, startWindows, statusWindows, stopWindows, uninstallWindows, windowsLogFile } from \"./windows\"\r\nimport {\r\n LOG_FILE,\r\n assertSupported,\r\n isMacOS,\r\n isLinux,\r\n isWindows,\r\n} from \"./shared\"\r\nimport type { CopilotProcess, DaemonInstallArgs } from \"./shared\"\r\n\r\n// ---------------------------------------------------------------------------\r\n// --all: find all copilot-api related processes\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction findAllCopilotProcesses(): CopilotProcess[] {\r\n if (isWindows()) {\r\n const result = spawnSync(\"powershell\", [\r\n \"-NoProfile\", \"-Command\",\r\n `Get-CimInstance Win32_Process -Filter \"CommandLine LIKE '%copilot-api%' AND ProcessId != $PID\" | ForEach-Object { \"$($_.ProcessId)|$($_.CommandLine)\" }`,\r\n ], { encoding: \"utf-8\", timeout: 10000 })\r\n if (result.status !== 0) return []\r\n const procs: CopilotProcess[] = []\r\n for (const line of result.stdout.trim().split(\"\\n\")) {\r\n if (!line.trim()) continue\r\n const sep = line.indexOf(\"|\")\r\n if (sep < 0) continue\r\n procs.push({ pid: line.slice(0, sep).trim(), command: line.slice(sep + 1).trim() })\r\n }\r\n return procs\r\n }\r\n\r\n try {\r\n const output = execSync(\r\n \"ps aux | grep -i copilot-api | grep -v grep\",\r\n { encoding: \"utf-8\", timeout: 5000 },\r\n )\r\n const procs: CopilotProcess[] = []\r\n for (const line of output.trim().split(\"\\n\")) {\r\n if (!line) continue\r\n const parts = line.trim().split(/\\s+/)\r\n if (parts.length < 11) continue\r\n const pid = parts[1]\r\n const command = parts.slice(10).join(\" \")\r\n procs.push({ pid, command })\r\n }\r\n return procs\r\n } catch {\r\n return []\r\n }\r\n}\r\n\r\nfunction statusAll(): void {\r\n if (isMacOS()) {\r\n const jobs = findAllCopilotLaunchdJobs()\r\n if (jobs.length > 0) {\r\n console.log(\"=== LaunchAgent Jobs ===\")\r\n for (const job of jobs) {\r\n console.log(`\\n Label: ${job.label}`)\r\n if (job.plistPath) console.log(` Plist: ${job.plistPath}`)\r\n else console.log(` Plist: (not found)`)\r\n console.log(` PID: ${job.pid ?? \"not running\"}`)\r\n }\r\n } else {\r\n console.log(\"No copilot-api LaunchAgent jobs found.\")\r\n }\r\n } else if (isWindows()) {\r\n statusWindows()\r\n } else {\r\n const units = findAllCopilotSystemdUnits()\r\n if (units.length > 0) {\r\n console.log(\"=== Systemd Units ===\")\r\n for (const unit of units) {\r\n const r = spawnSync(\r\n \"systemctl\",\r\n [\"--user\", \"status\", unit, \"--no-pager\"],\r\n { encoding: \"utf-8\", timeout: 5000 },\r\n )\r\n console.log(`\\n--- ${unit} ---`)\r\n console.log(r.stdout.trim())\r\n }\r\n } else {\r\n console.log(\"No copilot-api systemd units found.\")\r\n }\r\n }\r\n\r\n const procs = findAllCopilotProcesses()\r\n if (procs.length > 0) {\r\n console.log(\"\\n=== Processes ===\")\r\n for (const proc of procs) {\r\n console.log(` PID ${proc.pid}: ${proc.command}`)\r\n }\r\n }\r\n}\r\n\r\nfunction stopAll(): void {\r\n let stopped = 0\r\n\r\n if (isMacOS()) {\r\n const jobs = findAllCopilotLaunchdJobs()\r\n const domain = `gui/${process.getuid?.() ?? 501}`\r\n for (const job of jobs) {\r\n const jobTarget = `${domain}/${job.label}`\r\n console.log(`Stopping LaunchAgent '${job.label}'...`)\r\n spawnSync(\"launchctl\", [\"bootout\", jobTarget], {\r\n encoding: \"utf-8\",\r\n timeout: 15000,\r\n })\r\n stopped++\r\n }\r\n } else if (!isWindows()) {\r\n const units = findAllCopilotSystemdUnits()\r\n for (const unit of units) {\r\n console.log(`Stopping systemd unit '${unit}'...`)\r\n spawnSync(\"systemctl\", [\"--user\", \"stop\", unit], {\r\n encoding: \"utf-8\",\r\n timeout: 15000,\r\n })\r\n stopped++\r\n }\r\n }\r\n\r\n // Kill remaining processes\r\n const procs = findAllCopilotProcesses()\r\n for (const proc of procs) {\r\n console.log(`Killing PID ${proc.pid}: ${proc.command}`)\r\n if (isWindows()) {\r\n spawnSync(\"taskkill\", [\"/PID\", proc.pid, \"/F\"], { encoding: \"utf-8\", timeout: 5000 })\r\n stopped++\r\n } else {\r\n try {\r\n process.kill(Number.parseInt(proc.pid, 10), \"SIGTERM\")\r\n stopped++\r\n } catch {\r\n // already dead\r\n }\r\n }\r\n }\r\n\r\n if (stopped === 0) {\r\n console.log(\"No copilot-api processes found.\")\r\n } else {\r\n console.log(`\\nStopped/killed ${stopped} item(s).`)\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// CLI subcommands\r\n// ---------------------------------------------------------------------------\r\n\r\nconst installCmd = defineCommand({\r\n meta: {\r\n name: \"install\",\r\n description:\r\n \"Install xc-copilot-api daemon (launchd on macOS, systemd on Linux, Task Scheduler on Windows)\",\r\n },\r\n args: {\r\n npx: {\r\n type: \"boolean\",\r\n default: true,\r\n description:\r\n \"Use npx to run (auto-updates on restart). Set --no-npx to use direct binary.\",\r\n },\r\n port: {\r\n alias: \"p\",\r\n type: \"string\",\r\n default: \"4141\",\r\n description: \"Port for the API server\",\r\n },\r\n verbose: {\r\n alias: \"v\",\r\n type: \"boolean\",\r\n default: false,\r\n description: \"Enable verbose logging\",\r\n },\r\n \"account-type\": {\r\n alias: \"a\",\r\n type: \"string\",\r\n default: \"individual\",\r\n description: \"Account type (individual, business, enterprise)\",\r\n },\r\n \"github-token\": {\r\n alias: \"g\",\r\n type: \"string\",\r\n description: \"GitHub token to use\",\r\n },\r\n \"proxy-env\": {\r\n type: \"boolean\",\r\n default: false,\r\n description: \"Initialize proxy from environment variables\",\r\n },\r\n },\r\n run({ args }) {\r\n assertSupported()\r\n const installArgs: DaemonInstallArgs = {\r\n npx: args.npx,\r\n port: args.port,\r\n verbose: args.verbose,\r\n accountType: args[\"account-type\"],\r\n githubToken: args[\"github-token\"],\r\n proxyEnv: args[\"proxy-env\"],\r\n }\r\n if (isMacOS()) {\r\n installMacOS(installArgs)\r\n } else if (isWindows()) {\r\n installWindows(installArgs)\r\n } else {\r\n installLinux(installArgs)\r\n }\r\n },\r\n})\r\n\r\nconst uninstallCmd = defineCommand({\r\n meta: {\r\n name: \"uninstall\",\r\n description: \"Uninstall the daemon\",\r\n },\r\n run() {\r\n assertSupported()\r\n if (isMacOS()) {\r\n uninstallMacOS()\r\n } else if (isWindows()) {\r\n uninstallWindows()\r\n } else {\r\n uninstallLinux()\r\n }\r\n },\r\n})\r\n\r\nconst statusCmd = defineCommand({\r\n meta: {\r\n name: \"status\",\r\n description: \"Show daemon status (use --all to show all copilot-api instances)\",\r\n },\r\n args: {\r\n all: {\r\n type: \"boolean\",\r\n default: false,\r\n description:\r\n \"Show all copilot-api related daemons and processes\",\r\n },\r\n },\r\n run({ args }) {\r\n assertSupported()\r\n if (args.all) {\r\n statusAll()\r\n } else if (isMacOS()) {\r\n statusMacOS()\r\n } else if (isWindows()) {\r\n statusWindows()\r\n } else {\r\n statusLinux()\r\n }\r\n },\r\n})\r\n\r\nconst restartCmd = defineCommand({\r\n meta: {\r\n name: \"restart\",\r\n description:\r\n \"Restart the daemon (npx mode fetches latest version automatically)\",\r\n },\r\n run() {\r\n assertSupported()\r\n if (isMacOS()) {\r\n if (!startMacOS()) process.exit(1)\r\n } else if (isWindows()) {\r\n stopWindows()\r\n if (!startWindows()) process.exit(1)\r\n } else {\r\n stopLinux()\r\n if (!startLinux()) process.exit(1)\r\n }\r\n },\r\n})\r\n\r\nconst stopCmd = defineCommand({\r\n meta: {\r\n name: \"stop\",\r\n description: \"Stop the daemon (use --all to kill all copilot-api instances)\",\r\n },\r\n args: {\r\n all: {\r\n type: \"boolean\",\r\n default: false,\r\n description:\r\n \"Stop all copilot-api related daemons and kill all processes\",\r\n },\r\n },\r\n run({ args }) {\r\n assertSupported()\r\n if (args.all) {\r\n stopAll()\r\n } else if (isMacOS()) {\r\n if (!stopMacOS()) process.exit(1)\r\n } else if (isWindows()) {\r\n if (!stopWindows()) process.exit(1)\r\n } else {\r\n if (!stopLinux()) process.exit(1)\r\n }\r\n },\r\n})\r\n\r\nconst logsCmd = defineCommand({\r\n meta: {\r\n name: \"logs\",\r\n description: \"Show recent daemon logs\",\r\n },\r\n args: {\r\n follow: {\r\n alias: \"f\",\r\n type: \"boolean\",\r\n default: false,\r\n description: \"Follow log output (like tail -f)\",\r\n },\r\n lines: {\r\n alias: \"n\",\r\n type: \"string\",\r\n default: \"50\",\r\n description: \"Number of lines to show\",\r\n },\r\n },\r\n run({ args }) {\r\n assertSupported()\r\n const logPath = isWindows() ? windowsLogFile() : LOG_FILE\r\n if (!fs.existsSync(logPath)) {\r\n console.log(\"No log file found.\")\r\n return\r\n }\r\n\r\n if (isWindows()) {\r\n // Windows: use powershell Get-Content\r\n if (args.follow) {\r\n const { status } = spawnSync(\"powershell\", [\"-Command\", `Get-Content -Path '${logPath}' -Wait -Tail ${args.lines}`], { stdio: \"inherit\" })\r\n process.exit(status ?? 0)\r\n } else {\r\n const { status } = spawnSync(\"powershell\", [\"-Command\", `Get-Content -Path '${logPath}' -Tail ${args.lines}`], { stdio: \"inherit\" })\r\n process.exit(status ?? 0)\r\n }\r\n } else {\r\n if (args.follow) {\r\n const { status } = spawnSync(\"tail\", [\"-f\", logPath], { stdio: \"inherit\" })\r\n process.exit(status ?? 0)\r\n } else {\r\n const { status } = spawnSync(\"tail\", [\"-n\", args.lines, logPath], { stdio: \"inherit\" })\r\n process.exit(status ?? 0)\r\n }\r\n }\r\n },\r\n})\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main daemon command\r\n// ---------------------------------------------------------------------------\r\n\r\nexport const daemon = defineCommand({\r\n meta: {\r\n name: \"xc-copilot-api-daemon\",\r\n description:\r\n \"Manage xc-copilot-api daemon (install, status, restart, stop, uninstall, logs)\",\r\n },\r\n subCommands: {\r\n install: installCmd,\r\n uninstall: uninstallCmd,\r\n status: statusCmd,\r\n restart: restartCmd,\r\n stop: stopCmd,\r\n logs: logsCmd,\r\n },\r\n})\r\n","#!/usr/bin/env node\n\nimport { runMain } from \"citty\"\n\nimport { daemon } from \"./daemon/index\"\n\nawait runMain(daemon)\n"],"mappings":"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"}