@openagents-org/agent-launcher 0.1.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,178 @@
1
+ /**
2
+ * Autostart — register agent-connector daemon as a system service.
3
+ *
4
+ * - macOS: launchd plist
5
+ * - Linux: systemd user unit
6
+ * - Windows: Task Scheduler XML
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const { execSync } = require('child_process');
14
+ const { whichBinary, IS_WINDOWS } = require('./paths');
15
+
16
+ const IS_MACOS = process.platform === 'darwin';
17
+ const IS_LINUX = process.platform === 'linux' && !IS_MACOS;
18
+ const HOME = process.env.HOME || process.env.USERPROFILE || '';
19
+
20
+ const SERVICE_LABEL = 'org.openagents.connector';
21
+
22
+ /**
23
+ * Enable autostart on login.
24
+ */
25
+ function enable(configDir) {
26
+ const nodeBin = whichBinary('node') || process.execPath;
27
+ const cliPath = path.resolve(__dirname, '..', 'bin', 'agent-connector.js');
28
+
29
+ if (IS_MACOS) return _enableMacOS(nodeBin, cliPath, configDir);
30
+ if (IS_LINUX) return _enableLinux(nodeBin, cliPath, configDir);
31
+ if (IS_WINDOWS) return _enableWindows(nodeBin, cliPath, configDir);
32
+ throw new Error(`Autostart not supported on ${process.platform}`);
33
+ }
34
+
35
+ /**
36
+ * Disable autostart.
37
+ */
38
+ function disable() {
39
+ if (IS_MACOS) return _disableMacOS();
40
+ if (IS_LINUX) return _disableLinux();
41
+ if (IS_WINDOWS) return _disableWindows();
42
+ throw new Error(`Autostart not supported on ${process.platform}`);
43
+ }
44
+
45
+ /**
46
+ * Check if autostart is enabled.
47
+ */
48
+ function isEnabled() {
49
+ if (IS_MACOS) {
50
+ const plistPath = path.join(HOME, 'Library', 'LaunchAgents', `${SERVICE_LABEL}.plist`);
51
+ return fs.existsSync(plistPath);
52
+ }
53
+ if (IS_LINUX) {
54
+ const unitPath = path.join(HOME, '.config', 'systemd', 'user', 'openagents-connector.service');
55
+ return fs.existsSync(unitPath);
56
+ }
57
+ if (IS_WINDOWS) {
58
+ try {
59
+ execSync(`schtasks /Query /TN "OpenAgents Connector"`, { stdio: 'pipe', timeout: 5000 });
60
+ return true;
61
+ } catch {
62
+ return false;
63
+ }
64
+ }
65
+ return false;
66
+ }
67
+
68
+ // ---- macOS: launchd ----
69
+
70
+ function _enableMacOS(nodeBin, cliPath, configDir) {
71
+ const plistDir = path.join(HOME, 'Library', 'LaunchAgents');
72
+ fs.mkdirSync(plistDir, { recursive: true });
73
+
74
+ const plistPath = path.join(plistDir, `${SERVICE_LABEL}.plist`);
75
+ const logPath = path.join(configDir, 'daemon.log');
76
+
77
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
78
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
79
+ <plist version="1.0">
80
+ <dict>
81
+ <key>Label</key>
82
+ <string>${SERVICE_LABEL}</string>
83
+ <key>ProgramArguments</key>
84
+ <array>
85
+ <string>${nodeBin}</string>
86
+ <string>${cliPath}</string>
87
+ <string>up</string>
88
+ <string>--foreground</string>
89
+ </array>
90
+ <key>RunAtLoad</key>
91
+ <true/>
92
+ <key>KeepAlive</key>
93
+ <true/>
94
+ <key>StandardOutPath</key>
95
+ <string>${logPath}</string>
96
+ <key>StandardErrorPath</key>
97
+ <string>${logPath}</string>
98
+ <key>EnvironmentVariables</key>
99
+ <dict>
100
+ <key>PATH</key>
101
+ <string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>
102
+ </dict>
103
+ </dict>
104
+ </plist>`;
105
+
106
+ fs.writeFileSync(plistPath, plist, 'utf-8');
107
+ execSync(`launchctl load -w "${plistPath}"`, { stdio: 'pipe', timeout: 5000 });
108
+ return { enabled: true, path: plistPath };
109
+ }
110
+
111
+ function _disableMacOS() {
112
+ const plistPath = path.join(HOME, 'Library', 'LaunchAgents', `${SERVICE_LABEL}.plist`);
113
+ try {
114
+ execSync(`launchctl unload "${plistPath}"`, { stdio: 'pipe', timeout: 5000 });
115
+ } catch {}
116
+ try { fs.unlinkSync(plistPath); } catch {}
117
+ return { enabled: false };
118
+ }
119
+
120
+ // ---- Linux: systemd user unit ----
121
+
122
+ function _enableLinux(nodeBin, cliPath, configDir) {
123
+ const unitDir = path.join(HOME, '.config', 'systemd', 'user');
124
+ fs.mkdirSync(unitDir, { recursive: true });
125
+
126
+ const unitPath = path.join(unitDir, 'openagents-connector.service');
127
+
128
+ const unit = `[Unit]
129
+ Description=OpenAgents Connector Daemon
130
+ After=network.target
131
+
132
+ [Service]
133
+ Type=simple
134
+ ExecStart=${nodeBin} ${cliPath} up --foreground
135
+ Restart=on-failure
136
+ RestartSec=10
137
+ Environment=PATH=/usr/local/bin:/usr/bin:/bin
138
+
139
+ [Install]
140
+ WantedBy=default.target
141
+ `;
142
+
143
+ fs.writeFileSync(unitPath, unit, 'utf-8');
144
+ execSync('systemctl --user daemon-reload', { stdio: 'pipe', timeout: 5000 });
145
+ execSync('systemctl --user enable openagents-connector.service', { stdio: 'pipe', timeout: 5000 });
146
+ execSync('systemctl --user start openagents-connector.service', { stdio: 'pipe', timeout: 5000 });
147
+ return { enabled: true, path: unitPath };
148
+ }
149
+
150
+ function _disableLinux() {
151
+ try {
152
+ execSync('systemctl --user stop openagents-connector.service', { stdio: 'pipe', timeout: 5000 });
153
+ } catch {}
154
+ try {
155
+ execSync('systemctl --user disable openagents-connector.service', { stdio: 'pipe', timeout: 5000 });
156
+ } catch {}
157
+ const unitPath = path.join(HOME, '.config', 'systemd', 'user', 'openagents-connector.service');
158
+ try { fs.unlinkSync(unitPath); } catch {}
159
+ return { enabled: false };
160
+ }
161
+
162
+ // ---- Windows: Task Scheduler ----
163
+
164
+ function _enableWindows(nodeBin, cliPath, configDir) {
165
+ const taskName = 'OpenAgents Connector';
166
+ const cmd = `schtasks /Create /SC ONLOGON /TN "${taskName}" /TR "\\"${nodeBin}\\" \\"${cliPath}\\" up --foreground" /RL HIGHEST /F`;
167
+ execSync(cmd, { stdio: 'pipe', timeout: 10000 });
168
+ return { enabled: true, method: 'Task Scheduler' };
169
+ }
170
+
171
+ function _disableWindows() {
172
+ try {
173
+ execSync('schtasks /Delete /TN "OpenAgents Connector" /F', { stdio: 'pipe', timeout: 5000 });
174
+ } catch {}
175
+ return { enabled: false };
176
+ }
177
+
178
+ module.exports = { enable, disable, isEnabled };