agentel 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const os = require("os");
5
+ const path = require("path");
6
+ const { spawnSync } = require("child_process");
7
+ const { ensureDir } = require("./paths");
8
+
9
+ function autostartStatus() {
10
+ const platform = process.platform;
11
+ const target = autostartTarget();
12
+ return {
13
+ platform,
14
+ supported: Boolean(target),
15
+ enabled: target ? fs.existsSync(target.file) : false,
16
+ file: target?.file || "",
17
+ note: target?.note || unsupportedNote(platform)
18
+ };
19
+ }
20
+
21
+ function enableAutostart(options = {}) {
22
+ const target = autostartTarget();
23
+ if (!target) throw new Error(unsupportedNote(process.platform));
24
+ ensureDir(path.dirname(target.file));
25
+ fs.writeFileSync(target.file, target.content(), { mode: 0o600 });
26
+ if (options.load !== false && target.load) target.load(target.file);
27
+ return autostartStatus();
28
+ }
29
+
30
+ function disableAutostart() {
31
+ const target = autostartTarget();
32
+ if (!target) throw new Error(unsupportedNote(process.platform));
33
+ if (target.unload) target.unload(target.file);
34
+ try {
35
+ fs.unlinkSync(target.file);
36
+ } catch (error) {
37
+ if (error.code !== "ENOENT") throw error;
38
+ }
39
+ return autostartStatus();
40
+ }
41
+
42
+ function autostartTarget() {
43
+ if (process.platform === "darwin") return macLaunchAgent();
44
+ if (process.platform === "linux") return linuxUserUnit();
45
+ if (process.platform === "win32") return windowsTaskFile();
46
+ return null;
47
+ }
48
+
49
+ function macLaunchAgent() {
50
+ const file = path.join(os.homedir(), "Library", "LaunchAgents", "com.agentlog.supervisor.plist");
51
+ return {
52
+ file,
53
+ note: "macOS launchd user agent",
54
+ content: () => `<?xml version="1.0" encoding="UTF-8"?>
55
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
56
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
57
+ <plist version="1.0">
58
+ <dict>
59
+ <key>Label</key>
60
+ <string>com.agentlog.supervisor</string>
61
+ <key>ProgramArguments</key>
62
+ <array>
63
+ <string>${escapeXml(process.execPath)}</string>
64
+ <string>${escapeXml(cliPath())}</string>
65
+ <string>start</string>
66
+ <string>--foreground</string>
67
+ </array>
68
+ <key>RunAtLoad</key>
69
+ <true/>
70
+ <key>KeepAlive</key>
71
+ <dict>
72
+ <key>SuccessfulExit</key>
73
+ <false/>
74
+ </dict>
75
+ <key>StandardOutPath</key>
76
+ <string>${escapeXml(path.join(os.homedir(), "Library", "Logs", "agentlog", "agentlog.out.log"))}</string>
77
+ <key>StandardErrorPath</key>
78
+ <string>${escapeXml(path.join(os.homedir(), "Library", "Logs", "agentlog", "agentlog.err.log"))}</string>
79
+ </dict>
80
+ </plist>
81
+ `,
82
+ load: (plist) => spawnSync("launchctl", ["load", "-w", plist], { stdio: "ignore" }),
83
+ unload: (plist) => spawnSync("launchctl", ["unload", "-w", plist], { stdio: "ignore" })
84
+ };
85
+ }
86
+
87
+ function linuxUserUnit() {
88
+ const file = path.join(os.homedir(), ".config", "systemd", "user", "agentlog.service");
89
+ return {
90
+ file,
91
+ note: "systemd user service",
92
+ content: () => `[Unit]
93
+ Description=agentlog supervisor
94
+
95
+ [Service]
96
+ Type=simple
97
+ ExecStart=${quoteSystemd(process.execPath)} ${quoteSystemd(cliPath())} start --foreground
98
+ Restart=on-failure
99
+ RestartSec=5
100
+
101
+ [Install]
102
+ WantedBy=default.target
103
+ `,
104
+ load: () => {
105
+ spawnSync("systemctl", ["--user", "daemon-reload"], { stdio: "ignore" });
106
+ spawnSync("systemctl", ["--user", "enable", "--now", "agentlog.service"], { stdio: "ignore" });
107
+ },
108
+ unload: () => {
109
+ spawnSync("systemctl", ["--user", "disable", "--now", "agentlog.service"], { stdio: "ignore" });
110
+ spawnSync("systemctl", ["--user", "daemon-reload"], { stdio: "ignore" });
111
+ }
112
+ };
113
+ }
114
+
115
+ function windowsTaskFile() {
116
+ const file = path.join(os.homedir(), ".agentlog", "agentlog-autostart.cmd");
117
+ return {
118
+ file,
119
+ note: "Windows Scheduled Task helper command",
120
+ content: () => `@echo off\r\n"${process.execPath}" "${cliPath()}" start --foreground\r\n`,
121
+ load: () => {
122
+ spawnSync("schtasks", [
123
+ "/create",
124
+ "/tn",
125
+ "agentlog",
126
+ "/tr",
127
+ `"${process.execPath}" "${cliPath()}" start --foreground`,
128
+ "/sc",
129
+ "onlogon",
130
+ "/f"
131
+ ]);
132
+ },
133
+ unload: () => spawnSync("schtasks", ["/delete", "/tn", "agentlog", "/f"])
134
+ };
135
+ }
136
+
137
+ function cliPath() {
138
+ return path.resolve(__dirname, "..", "bin", "agentlog.js");
139
+ }
140
+
141
+ function recallInvocation() {
142
+ const globalRecall = commandOnPath("agentlog-recall");
143
+ if (globalRecall) return { command: globalRecall, args: [] };
144
+ return {
145
+ command: process.execPath,
146
+ args: [path.resolve(__dirname, "..", "bin", "agentlog-recall.js")]
147
+ };
148
+ }
149
+
150
+ function commandOnPath(command) {
151
+ const result = process.platform === "win32"
152
+ ? spawnSync("where", [command], { encoding: "utf8" })
153
+ : spawnSync("sh", ["-lc", `command -v ${shellQuote(command)}`], { encoding: "utf8" });
154
+ return result.status === 0 ? String(result.stdout || "").trim().split(/\r?\n/)[0] : "";
155
+ }
156
+
157
+ function shellQuote(value) {
158
+ return `'${String(value).replace(/'/g, "'\\''")}'`;
159
+ }
160
+
161
+ function unsupportedNote(platform) {
162
+ return `autostart is not implemented for ${platform}`;
163
+ }
164
+
165
+ function quoteSystemd(value) {
166
+ return String(value).replace(/ /g, "\\x20");
167
+ }
168
+
169
+ function escapeXml(value) {
170
+ return String(value)
171
+ .replace(/&/g, "&amp;")
172
+ .replace(/</g, "&lt;")
173
+ .replace(/>/g, "&gt;")
174
+ .replace(/"/g, "&quot;");
175
+ }
176
+
177
+ module.exports = {
178
+ autostartStatus,
179
+ disableAutostart,
180
+ enableAutostart,
181
+ recallInvocation
182
+ };