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.
- package/dist/daemon-main.js +153 -123
- package/dist/daemon-main.js.map +1 -1
- package/dist/main.js +23 -1
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/dist/daemon-main.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
314
|
-
return path.join(windowsAppDir(), "launcher.
|
|
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
|
-
|
|
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
|
|
406
|
+
const launcherCmd = windowsLauncherCmdPath();
|
|
328
407
|
fs.mkdirSync(appDir, { recursive: true });
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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(
|
|
336
|
-
const
|
|
337
|
-
"
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
"
|
|
344
|
-
|
|
345
|
-
|
|
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:
|
|
427
|
+
timeout: 15e3
|
|
349
428
|
});
|
|
350
429
|
if (result.status !== 0) {
|
|
351
|
-
console.error(`Failed to
|
|
430
|
+
console.error(`Failed to create scheduled task: ${(result.stderr || "").trim()}`);
|
|
352
431
|
process.exit(1);
|
|
353
432
|
}
|
|
354
|
-
console.log(`Installed
|
|
355
|
-
console.log(` Launcher: ${
|
|
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("
|
|
363
|
-
"delete",
|
|
364
|
-
"
|
|
365
|
-
|
|
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
|
|
373
|
-
if (fs.existsSync(
|
|
374
|
-
|
|
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
|
-
|
|
380
|
-
|
|
381
|
-
|
|
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
|
-
|
|
434
|
-
"query",
|
|
435
|
-
"
|
|
436
|
-
|
|
437
|
-
|
|
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
|
-
})
|
|
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
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
|
|
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
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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,
|
|
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: {
|
package/dist/daemon-main.js.map
CHANGED
|
@@ -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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"}
|