xc-copilot-api 1.1.0 → 1.1.2
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 +193 -135
- package/dist/daemon-main.js.map +1 -1
- package/dist/main.js +1 -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,29 +539,32 @@ function statusWindows() {
|
|
|
456
539
|
console.log(` Log: ${logFile} (${(stat.size / 1024).toFixed(1)} KB)`);
|
|
457
540
|
}
|
|
458
541
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
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
|
|
542
|
+
|
|
543
|
+
//#endregion
|
|
544
|
+
//#region src/daemon/index.ts
|
|
545
|
+
function findAllCopilotProcesses() {
|
|
546
|
+
if (isWindows()) {
|
|
547
|
+
const result = spawnSync("powershell", [
|
|
548
|
+
"-NoProfile",
|
|
549
|
+
"-Command",
|
|
550
|
+
`Get-CimInstance Win32_Process -Filter "CommandLine LIKE '%copilot-api%' AND ProcessId != $PID" | ForEach-Object { "$($_.ProcessId)|$($_.CommandLine)" }`
|
|
551
|
+
], {
|
|
552
|
+
encoding: "utf-8",
|
|
553
|
+
timeout: 1e4
|
|
477
554
|
});
|
|
555
|
+
if (result.status !== 0) return [];
|
|
556
|
+
const procs = [];
|
|
557
|
+
for (const line of result.stdout.trim().split("\n")) {
|
|
558
|
+
if (!line.trim()) continue;
|
|
559
|
+
const sep = line.indexOf("|");
|
|
560
|
+
if (sep < 0) continue;
|
|
561
|
+
procs.push({
|
|
562
|
+
pid: line.slice(0, sep).trim(),
|
|
563
|
+
command: line.slice(sep + 1).trim()
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
return procs;
|
|
478
567
|
}
|
|
479
|
-
return jobs;
|
|
480
|
-
}
|
|
481
|
-
function findAllCopilotProcesses() {
|
|
482
568
|
try {
|
|
483
569
|
const output = execSync("ps aux | grep -i copilot-api | grep -v grep", {
|
|
484
570
|
encoding: "utf-8",
|
|
@@ -501,25 +587,6 @@ function findAllCopilotProcesses() {
|
|
|
501
587
|
return [];
|
|
502
588
|
}
|
|
503
589
|
}
|
|
504
|
-
function findAllCopilotSystemdUnits() {
|
|
505
|
-
const result = spawnSync("systemctl", [
|
|
506
|
-
"--user",
|
|
507
|
-
"list-units",
|
|
508
|
-
"--all",
|
|
509
|
-
"--no-pager",
|
|
510
|
-
"--plain"
|
|
511
|
-
], {
|
|
512
|
-
encoding: "utf-8",
|
|
513
|
-
timeout: 5e3
|
|
514
|
-
});
|
|
515
|
-
if (result.status !== 0) return [];
|
|
516
|
-
const units = [];
|
|
517
|
-
for (const line of result.stdout.split("\n")) if (line.toLowerCase().includes("copilot")) {
|
|
518
|
-
const unit = line.trim().split(/\s+/)[0];
|
|
519
|
-
if (unit) units.push(unit);
|
|
520
|
-
}
|
|
521
|
-
return units;
|
|
522
|
-
}
|
|
523
590
|
function statusAll() {
|
|
524
591
|
if (isMacOS()) {
|
|
525
592
|
const jobs = findAllCopilotLaunchdJobs();
|
|
@@ -532,12 +599,8 @@ function statusAll() {
|
|
|
532
599
|
console.log(` PID: ${job.pid ?? "not running"}`);
|
|
533
600
|
}
|
|
534
601
|
} else console.log("No copilot-api LaunchAgent jobs found.");
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
console.log("\n=== Processes ===");
|
|
538
|
-
for (const proc of procs) console.log(` PID ${proc.pid}: ${proc.command}`);
|
|
539
|
-
}
|
|
540
|
-
} else {
|
|
602
|
+
} else if (isWindows()) statusWindows();
|
|
603
|
+
else {
|
|
541
604
|
const units = findAllCopilotSystemdUnits();
|
|
542
605
|
if (units.length > 0) {
|
|
543
606
|
console.log("=== Systemd Units ===");
|
|
@@ -555,11 +618,11 @@ function statusAll() {
|
|
|
555
618
|
console.log(r.stdout.trim());
|
|
556
619
|
}
|
|
557
620
|
} else console.log("No copilot-api systemd units found.");
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
}
|
|
621
|
+
}
|
|
622
|
+
const procs = findAllCopilotProcesses();
|
|
623
|
+
if (procs.length > 0) {
|
|
624
|
+
console.log("\n=== Processes ===");
|
|
625
|
+
for (const proc of procs) console.log(` PID ${proc.pid}: ${proc.command}`);
|
|
563
626
|
}
|
|
564
627
|
}
|
|
565
628
|
function stopAll() {
|
|
@@ -576,7 +639,7 @@ function stopAll() {
|
|
|
576
639
|
});
|
|
577
640
|
stopped++;
|
|
578
641
|
}
|
|
579
|
-
} else {
|
|
642
|
+
} else if (!isWindows()) {
|
|
580
643
|
const units = findAllCopilotSystemdUnits();
|
|
581
644
|
for (const unit of units) {
|
|
582
645
|
console.log(`Stopping systemd unit '${unit}'...`);
|
|
@@ -594,7 +657,17 @@ function stopAll() {
|
|
|
594
657
|
const procs = findAllCopilotProcesses();
|
|
595
658
|
for (const proc of procs) {
|
|
596
659
|
console.log(`Killing PID ${proc.pid}: ${proc.command}`);
|
|
597
|
-
|
|
660
|
+
if (isWindows()) {
|
|
661
|
+
spawnSync("taskkill", [
|
|
662
|
+
"/PID",
|
|
663
|
+
proc.pid,
|
|
664
|
+
"/F"
|
|
665
|
+
], {
|
|
666
|
+
encoding: "utf-8",
|
|
667
|
+
timeout: 5e3
|
|
668
|
+
});
|
|
669
|
+
stopped++;
|
|
670
|
+
} else try {
|
|
598
671
|
process.kill(Number.parseInt(proc.pid, 10), "SIGTERM");
|
|
599
672
|
stopped++;
|
|
600
673
|
} catch {}
|
|
@@ -602,25 +675,10 @@ function stopAll() {
|
|
|
602
675
|
if (stopped === 0) console.log("No copilot-api processes found.");
|
|
603
676
|
else console.log(`\nStopped/killed ${stopped} item(s).`);
|
|
604
677
|
}
|
|
605
|
-
function isMacOS() {
|
|
606
|
-
return process.platform === "darwin";
|
|
607
|
-
}
|
|
608
|
-
function isLinux() {
|
|
609
|
-
return process.platform === "linux";
|
|
610
|
-
}
|
|
611
|
-
function isWindows() {
|
|
612
|
-
return process.platform === "win32";
|
|
613
|
-
}
|
|
614
|
-
function assertSupported() {
|
|
615
|
-
if (!isMacOS() && !isLinux() && !isWindows()) {
|
|
616
|
-
console.error("Daemon management is only supported on macOS, Linux, and Windows.");
|
|
617
|
-
process.exit(1);
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
678
|
const installCmd = defineCommand({
|
|
621
679
|
meta: {
|
|
622
680
|
name: "install",
|
|
623
|
-
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)"
|
|
624
682
|
},
|
|
625
683
|
args: {
|
|
626
684
|
npx: {
|