@openagents-org/agent-connector 0.2.7 → 0.2.8
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/package.json +1 -1
- package/src/autostart.js +178 -0
- package/src/cli.js +13 -0
- package/src/installer.js +8 -3
package/package.json
CHANGED
package/src/autostart.js
ADDED
|
@@ -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 };
|
package/src/cli.js
CHANGED
|
@@ -327,6 +327,17 @@ async function cmdLogs(connector, flags, positional) {
|
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
+
async function cmdAutostart(connector, flags) {
|
|
331
|
+
const autostart = require('./autostart');
|
|
332
|
+
if (flags.disable) {
|
|
333
|
+
autostart.disable();
|
|
334
|
+
print('Autostart disabled.');
|
|
335
|
+
} else {
|
|
336
|
+
const result = autostart.enable(connector._config ? connector._config.configDir : require('path').join(require('os').homedir(), '.openagents'));
|
|
337
|
+
print(`Autostart enabled.${result.path ? ` Config: ${result.path}` : ''}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
330
341
|
async function cmdWorkspace(connector, flags, positional) {
|
|
331
342
|
const sub = positional[0] || 'list';
|
|
332
343
|
const subArgs = positional.slice(1);
|
|
@@ -461,6 +472,7 @@ Commands:
|
|
|
461
472
|
connect <agent> <token> Connect agent to workspace
|
|
462
473
|
disconnect <agent> Disconnect agent from workspace
|
|
463
474
|
env <type> [--set K=V] View/set env vars for agent type
|
|
475
|
+
autostart [--disable] Enable/disable auto-start on login
|
|
464
476
|
test-llm <type> Test LLM connection
|
|
465
477
|
logs [agent] [--lines N] View daemon logs
|
|
466
478
|
workspace create [name] Create a new workspace
|
|
@@ -502,6 +514,7 @@ async function main() {
|
|
|
502
514
|
connect: () => cmdConnect(connector, flags, positional),
|
|
503
515
|
disconnect: () => cmdDisconnect(connector, flags, positional),
|
|
504
516
|
logs: () => cmdLogs(connector, flags, positional),
|
|
517
|
+
autostart: () => cmdAutostart(connector, flags),
|
|
505
518
|
workspace: () => cmdWorkspace(connector, flags, positional),
|
|
506
519
|
env: () => cmdEnv(connector, flags, positional),
|
|
507
520
|
'test-llm': () => cmdTestLLM(connector, flags, positional),
|
package/src/installer.js
CHANGED
|
@@ -235,13 +235,18 @@ class Installer {
|
|
|
235
235
|
env.PATH = execDir + sep + (env.PATH || '');
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
// On Windows,
|
|
239
|
-
|
|
238
|
+
// On Windows, use cmd.exe explicitly with UTF-8 codepage
|
|
239
|
+
let shellCmd = cmd;
|
|
240
|
+
let shellOpt = true;
|
|
241
|
+
if (process.platform === 'win32') {
|
|
242
|
+
shellCmd = `cmd.exe /C "chcp 65001 >nul & ${cmd}"`;
|
|
243
|
+
shellOpt = false; // we're specifying the shell ourselves
|
|
244
|
+
}
|
|
240
245
|
|
|
241
246
|
exec(shellCmd, {
|
|
242
247
|
encoding: 'utf-8',
|
|
243
248
|
timeout: timeoutMs,
|
|
244
|
-
shell:
|
|
249
|
+
shell: shellOpt,
|
|
245
250
|
env,
|
|
246
251
|
}, (error, stdout, stderr) => {
|
|
247
252
|
const output = ((stdout || '') + '\n' + (stderr || '')).trim();
|