@agentsoc/beacon 0.0.4 → 0.0.6
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/README.md +2 -2
- package/dist/cli.js +97 -242
- package/dist/service-install.d.ts.map +1 -1
- package/dist/service-install.js +35 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ Install the background service daemon (systemd on Linux, launchd on macOS):
|
|
|
98
98
|
sudo beacon install
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
On macOS the plist is written under `/Library/LaunchDaemons/`, and on Linux the unit file goes under `/etc/systemd/system/`—both require root, so use `sudo`. If `sudo` cannot find `beacon` (for example with nvm), run `sudo env "PATH=$PATH" beacon install` or invoke the CLI with the full path to the global binary.
|
|
101
|
+
On macOS the plist is written under `/Library/LaunchDaemons/`, and on Linux the unit file goes under `/etc/systemd/system/`—both require root, so use `sudo`. The service is configured to **run as your login user** (via `SUDO_USER` when you use `sudo`), so it uses the same config directory as `beacon config`—not root’s home. If `sudo` cannot find `beacon` (for example with nvm), run `sudo env "PATH=$PATH" beacon install` or invoke the CLI with the full path to the global binary.
|
|
102
102
|
|
|
103
103
|
### Status and stats
|
|
104
104
|
|
|
@@ -110,7 +110,7 @@ beacon status
|
|
|
110
110
|
|
|
111
111
|
Use `beacon status --json` for machine-readable output (includes `validateKeyUrl` on errors).
|
|
112
112
|
|
|
113
|
-
After successful batches, the CLI updates **`stats.json`** next to your config (same config directory as `config.json`—for example `~/Library/Application Support/agentsoc-beacon/` on macOS). The file tracks `logsForwarded`, `batchesSucceeded`, `batchesFailed`, optional `lastError`, and `updatedAt`.
|
|
113
|
+
After successful batches, the CLI updates **`stats.json`** next to your config (same config directory as `config.json`—for example `~/Library/Application Support/agentsoc-beacon/` on macOS). The file tracks `logsForwarded`, `batchesSucceeded`, `batchesFailed`, optional `lastError`, and `updatedAt`. The background service runs as the installing user (see Install Service above), so stats stay alongside your user config.
|
|
114
114
|
|
|
115
115
|
The marketing site’s product demo terminal runs through **`beacon status`** so visitors can see a sample of this output.
|
|
116
116
|
|
package/dist/cli.js
CHANGED
|
@@ -1,243 +1,98 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
.option("-k, --key <key>", "AgentSOC API Key")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const labelW = 26;
|
|
102
|
-
const line = (label, value) => {
|
|
103
|
-
console.log(` ${label.padEnd(labelW)}${value}`);
|
|
104
|
-
};
|
|
105
|
-
console.log("\n AgentSOC Beacon — Status\n");
|
|
106
|
-
console.log(" Account");
|
|
107
|
-
if (context.ok) {
|
|
108
|
-
line("Organization", context.organizationName ??
|
|
109
|
-
"(name unavailable — check platform API / database)");
|
|
110
|
-
line("API key", context.apiKeyName);
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
line("Connection", context.message);
|
|
114
|
-
}
|
|
115
|
-
console.log("\n Service");
|
|
116
|
-
line(`Daemon (${svc.manager})`, svc.installed ? svc.stateLabel : "not installed");
|
|
117
|
-
if (svc.active === true)
|
|
118
|
-
line("Running", "yes");
|
|
119
|
-
else if (svc.active === false)
|
|
120
|
-
line("Running", "no");
|
|
121
|
-
else
|
|
122
|
-
line("Running", "n/a");
|
|
123
|
-
if (svc.detail)
|
|
124
|
-
line("Note", svc.detail);
|
|
125
|
-
console.log("\n Forwarding (this machine)");
|
|
126
|
-
line("Log entries forwarded", String(stats.logsForwarded));
|
|
127
|
-
line("Successful batches", String(stats.batchesSucceeded));
|
|
128
|
-
line("Failed batches", String(stats.batchesFailed));
|
|
129
|
-
if (stats.updatedAt && stats.updatedAt !== new Date(0).toISOString()) {
|
|
130
|
-
line("Last stats update", stats.updatedAt);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
line("Last stats update", "(none yet)");
|
|
134
|
-
}
|
|
135
|
-
if (stats.lastError) {
|
|
136
|
-
line("Last error", stats.lastError);
|
|
137
|
-
}
|
|
138
|
-
console.log();
|
|
139
|
-
});
|
|
140
|
-
program
|
|
141
|
-
.command("update")
|
|
142
|
-
.description("Check for a newer Beacon CLI and optionally install it")
|
|
143
|
-
.option("--json", "Print machine-readable JSON on stdout")
|
|
144
|
-
.option("-y, --yes", "Run npm install -g @agentsoc/beacon@latest (non-interactive upgrade)")
|
|
145
|
-
.action(async (opts) => {
|
|
146
|
-
const current = BEACON_VERSION;
|
|
147
|
-
const fetched = await fetchBeaconUpdateFromNpm();
|
|
148
|
-
if (opts.json) {
|
|
149
|
-
const latest = fetched.ok ? fetched.info.latestVersion : null;
|
|
150
|
-
const outdated = latest != null &&
|
|
151
|
-
latest.length > 0 &&
|
|
152
|
-
semverLessThan(current, latest);
|
|
153
|
-
console.log(JSON.stringify({
|
|
154
|
-
currentVersion: current,
|
|
155
|
-
registry: "https://registry.npmjs.org/@agentsoc%2fbeacon",
|
|
156
|
-
remote: fetched.ok ? fetched.info : null,
|
|
157
|
-
error: fetched.ok ? undefined : fetched.message,
|
|
158
|
-
updateAvailable: fetched.ok ? outdated : null,
|
|
159
|
-
}, null, 2));
|
|
160
|
-
if (!fetched.ok)
|
|
161
|
-
process.exit(1);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
if (!fetched.ok) {
|
|
165
|
-
console.error(`[beacon] Could not reach npm registry: ${fetched.message}`);
|
|
166
|
-
console.error("[beacon] You can still run: npm install -g @agentsoc/beacon@latest");
|
|
167
|
-
process.exit(1);
|
|
168
|
-
}
|
|
169
|
-
const { info } = fetched;
|
|
170
|
-
const latest = info.latestVersion;
|
|
171
|
-
console.log("\n AgentSOC Beacon — Update check\n");
|
|
172
|
-
console.log(` This install ${current}`);
|
|
173
|
-
if (latest) {
|
|
174
|
-
console.log(` Latest on registry ${latest}`);
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
console.log(" Latest on registry (unavailable — unexpected npm response)");
|
|
178
|
-
}
|
|
179
|
-
const canCompare = Boolean(latest && latest.length > 0);
|
|
180
|
-
const outdated = canCompare && semverLessThan(current, latest);
|
|
181
|
-
if (canCompare && !outdated) {
|
|
182
|
-
console.log("\n You are on the latest published version.\n");
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
if (canCompare && outdated) {
|
|
186
|
-
console.log("\n A newer version is available.\n");
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
console.log("\n Compare versions manually, or reinstall with:\n");
|
|
190
|
-
}
|
|
191
|
-
console.log(` ${info.install.npm}`);
|
|
192
|
-
console.log(` ${info.install.bun}`);
|
|
193
|
-
console.log(` ${info.install.pnpm}`);
|
|
194
|
-
if (info.docsUrl) {
|
|
195
|
-
console.log(`\n Docs: ${info.docsUrl}`);
|
|
196
|
-
}
|
|
197
|
-
if (opts.yes) {
|
|
198
|
-
if (!outdated && canCompare) {
|
|
199
|
-
console.log("\n[beacon] Already up to date — skipping install.\n");
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
console.log("\n[beacon] Running npm install -g @agentsoc/beacon@latest …\n");
|
|
203
|
-
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
204
|
-
try {
|
|
205
|
-
execFileSync(npm, ["install", "-g", "@agentsoc/beacon@latest"], { stdio: "inherit", env: process.env });
|
|
206
|
-
console.log("\n[beacon] Update finished. Run `beacon --version` to verify.\n");
|
|
207
|
-
}
|
|
208
|
-
catch {
|
|
209
|
-
process.exit(1);
|
|
210
|
-
}
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
console.log("\n To upgrade now, run the same command with --yes\n");
|
|
214
|
-
});
|
|
215
|
-
program
|
|
216
|
-
.command("run")
|
|
217
|
-
.description("Run the forwarder daemon (foreground)")
|
|
218
|
-
.option("--batch-size <n>", "Batch size", "25")
|
|
219
|
-
.option("--flush-ms <n>", "Flush interval in ms", "2000")
|
|
220
|
-
.action(async (options) => {
|
|
221
|
-
const config = await loadConfig();
|
|
222
|
-
const apiKey = resolveBeaconApiKey(config);
|
|
223
|
-
const ingestUrl = resolveIngestUrl(config);
|
|
224
|
-
if (!apiKey) {
|
|
225
|
-
console.error(`[beacon] ${BEACON_CONFIG_REQUIRED_MESSAGE}`);
|
|
226
|
-
process.exit(1);
|
|
227
|
-
}
|
|
228
|
-
console.log("[beacon] Starting in foreground...");
|
|
229
|
-
const beacon = await runBeacon({
|
|
230
|
-
apiKey,
|
|
231
|
-
ingestUrl,
|
|
232
|
-
batchSize: parseInt(options.batchSize, 10),
|
|
233
|
-
flushMs: parseInt(options.flushMs, 10),
|
|
234
|
-
});
|
|
235
|
-
const stop = async () => {
|
|
236
|
-
console.log("\n[beacon] Stopping...");
|
|
237
|
-
await beacon.stop();
|
|
238
|
-
process.exit(0);
|
|
239
|
-
};
|
|
240
|
-
process.on("SIGINT", stop);
|
|
241
|
-
process.on("SIGTERM", stop);
|
|
242
|
-
});
|
|
243
|
-
program.parse(process.argv);
|
|
2
|
+
import{createRequire as r0}from"node:module";var p0=Object.create;var{getPrototypeOf:s0,defineProperty:Q0,getOwnPropertyNames:i0}=Object;var n0=Object.prototype.hasOwnProperty;var o0=($,z,J)=>{J=$!=null?p0(s0($)):{};let Q=z||!$||!$.__esModule?Q0(J,"default",{value:$,enumerable:!0}):J;for(let Y of i0($))if(!n0.call(Q,Y))Q0(Q,Y,{get:()=>$[Y],enumerable:!0});return Q};var j=($,z)=>()=>(z||$((z={exports:{}}).exports,z),z.exports);var V=r0(import.meta.url);var N=j((t0)=>{class v extends Error{constructor($,z,J){super(J);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=z,this.exitCode=$,this.nestedError=void 0}}class Y0 extends v{constructor($){super(1,"commander.invalidArgument",$);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}}t0.CommanderError=v;t0.InvalidArgumentError=Y0});var F=j((J1)=>{var{InvalidArgumentError:$1}=N();class Z0{constructor($,z){switch(this.description=z||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,$[0]){case"<":this.required=!0,this._name=$.slice(1,-1);break;case"[":this.required=!1,this._name=$.slice(1,-1);break;default:this.required=!0,this._name=$;break}if(this._name.length>3&&this._name.slice(-3)==="...")this.variadic=!0,this._name=this._name.slice(0,-3)}name(){return this._name}_concatValue($,z){if(z===this.defaultValue||!Array.isArray(z))return[$];return z.concat($)}default($,z){return this.defaultValue=$,this.defaultValueDescription=z,this}argParser($){return this.parseArg=$,this}choices($){return this.argChoices=$.slice(),this.parseArg=(z,J)=>{if(!this.argChoices.includes(z))throw new $1(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(z,J);return z},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}}function z1($){let z=$.name()+($.variadic===!0?"...":"");return $.required?"<"+z+">":"["+z+"]"}J1.Argument=Z0;J1.humanReadableArgName=z1});var h=j((q1)=>{var{humanReadableArgName:Z1}=F();class q0{constructor(){this.helpWidth=void 0,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}visibleCommands($){let z=$.commands.filter((J)=>!J._hidden);if($._hasImplicitHelpCommand()){let[,J,Q]=$._helpCommandnameAndArgs.match(/([^ ]+) *(.*)/),Y=$.createCommand(J).helpOption(!1);if(Y.description($._helpCommandDescription),Q)Y.arguments(Q);z.push(Y)}if(this.sortSubcommands)z.sort((J,Q)=>{return J.name().localeCompare(Q.name())});return z}compareOptions($,z){let J=(Q)=>{return Q.short?Q.short.replace(/^-/,""):Q.long.replace(/^--/,"")};return J($).localeCompare(J(z))}visibleOptions($){let z=$.options.filter((Y)=>!Y.hidden),J=$._hasHelpOption&&$._helpShortFlag&&!$._findOption($._helpShortFlag),Q=$._hasHelpOption&&!$._findOption($._helpLongFlag);if(J||Q){let Y;if(!J)Y=$.createOption($._helpLongFlag,$._helpDescription);else if(!Q)Y=$.createOption($._helpShortFlag,$._helpDescription);else Y=$.createOption($._helpFlags,$._helpDescription);z.push(Y)}if(this.sortOptions)z.sort(this.compareOptions);return z}visibleGlobalOptions($){if(!this.showGlobalOptions)return[];let z=[];for(let J=$.parent;J;J=J.parent){let Q=J.options.filter((Y)=>!Y.hidden);z.push(...Q)}if(this.sortOptions)z.sort(this.compareOptions);return z}visibleArguments($){if($._argsDescription)$.registeredArguments.forEach((z)=>{z.description=z.description||$._argsDescription[z.name()]||""});if($.registeredArguments.find((z)=>z.description))return $.registeredArguments;return[]}subcommandTerm($){let z=$.registeredArguments.map((J)=>Z1(J)).join(" ");return $._name+($._aliases[0]?"|"+$._aliases[0]:"")+($.options.length?" [options]":"")+(z?" "+z:"")}optionTerm($){return $.flags}argumentTerm($){return $.name()}longestSubcommandTermLength($,z){return z.visibleCommands($).reduce((J,Q)=>{return Math.max(J,z.subcommandTerm(Q).length)},0)}longestOptionTermLength($,z){return z.visibleOptions($).reduce((J,Q)=>{return Math.max(J,z.optionTerm(Q).length)},0)}longestGlobalOptionTermLength($,z){return z.visibleGlobalOptions($).reduce((J,Q)=>{return Math.max(J,z.optionTerm(Q).length)},0)}longestArgumentTermLength($,z){return z.visibleArguments($).reduce((J,Q)=>{return Math.max(J,z.argumentTerm(Q).length)},0)}commandUsage($){let z=$._name;if($._aliases[0])z=z+"|"+$._aliases[0];let J="";for(let Q=$.parent;Q;Q=Q.parent)J=Q.name()+" "+J;return J+z+" "+$.usage()}commandDescription($){return $.description()}subcommandDescription($){return $.summary()||$.description()}optionDescription($){let z=[];if($.argChoices)z.push(`choices: ${$.argChoices.map((J)=>JSON.stringify(J)).join(", ")}`);if($.defaultValue!==void 0){if($.required||$.optional||$.isBoolean()&&typeof $.defaultValue==="boolean")z.push(`default: ${$.defaultValueDescription||JSON.stringify($.defaultValue)}`)}if($.presetArg!==void 0&&$.optional)z.push(`preset: ${JSON.stringify($.presetArg)}`);if($.envVar!==void 0)z.push(`env: ${$.envVar}`);if(z.length>0)return`${$.description} (${z.join(", ")})`;return $.description}argumentDescription($){let z=[];if($.argChoices)z.push(`choices: ${$.argChoices.map((J)=>JSON.stringify(J)).join(", ")}`);if($.defaultValue!==void 0)z.push(`default: ${$.defaultValueDescription||JSON.stringify($.defaultValue)}`);if(z.length>0){let J=`(${z.join(", ")})`;if($.description)return`${$.description} ${J}`;return J}return $.description}formatHelp($,z){let J=z.padWidth($,z),Q=z.helpWidth||80,Y=2,Z=2;function B(U,H){if(H){let x=`${U.padEnd(J+2)}${H}`;return z.wrap(x,Q-2,J+2)}return U}function q(U){return U.join(`
|
|
3
|
+
`).replace(/^/gm," ".repeat(2))}let X=[`Usage: ${z.commandUsage($)}`,""],G=z.commandDescription($);if(G.length>0)X=X.concat([z.wrap(G,Q,0),""]);let W=z.visibleArguments($).map((U)=>{return B(z.argumentTerm(U),z.argumentDescription(U))});if(W.length>0)X=X.concat(["Arguments:",q(W),""]);let K=z.visibleOptions($).map((U)=>{return B(z.optionTerm(U),z.optionDescription(U))});if(K.length>0)X=X.concat(["Options:",q(K),""]);if(this.showGlobalOptions){let U=z.visibleGlobalOptions($).map((H)=>{return B(z.optionTerm(H),z.optionDescription(H))});if(U.length>0)X=X.concat(["Global Options:",q(U),""])}let T=z.visibleCommands($).map((U)=>{return B(z.subcommandTerm(U),z.subcommandDescription(U))});if(T.length>0)X=X.concat(["Commands:",q(T),""]);return X.join(`
|
|
4
|
+
`)}padWidth($,z){return Math.max(z.longestOptionTermLength($,z),z.longestGlobalOptionTermLength($,z),z.longestSubcommandTermLength($,z),z.longestArgumentTermLength($,z))}wrap($,z,J,Q=40){let Z=new RegExp(`[\\n][${" \\f\\t\\v - \uFEFF"}]+`);if($.match(Z))return $;let B=z-J;if(B<Q)return $;let q=$.slice(0,J),X=$.slice(J).replace(`\r
|
|
5
|
+
`,`
|
|
6
|
+
`),G=" ".repeat(J),K=`\\s${""}`,T=new RegExp(`
|
|
7
|
+
|.{1,${B-1}}([${K}]|$)|[^${K}]+?([${K}]|$)`,"g"),U=X.match(T)||[];return q+U.map((H,x)=>{if(H===`
|
|
8
|
+
`)return"";return(x>0?G:"")+H.trimEnd()}).join(`
|
|
9
|
+
`)}}q1.Help=q0});var u=j((W1)=>{var{InvalidArgumentError:X1}=N();class B0{constructor($,z){this.flags=$,this.description=z||"",this.required=$.includes("<"),this.optional=$.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test($),this.mandatory=!1;let J=G0($);if(this.short=J.shortFlag,this.long=J.longFlag,this.negate=!1,this.long)this.negate=this.long.startsWith("--no-");this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0}default($,z){return this.defaultValue=$,this.defaultValueDescription=z,this}preset($){return this.presetArg=$,this}conflicts($){return this.conflictsWith=this.conflictsWith.concat($),this}implies($){let z=$;if(typeof $==="string")z={[$]:!0};return this.implied=Object.assign(this.implied||{},z),this}env($){return this.envVar=$,this}argParser($){return this.parseArg=$,this}makeOptionMandatory($=!0){return this.mandatory=!!$,this}hideHelp($=!0){return this.hidden=!!$,this}_concatValue($,z){if(z===this.defaultValue||!Array.isArray(z))return[$];return z.concat($)}choices($){return this.argChoices=$.slice(),this.parseArg=(z,J)=>{if(!this.argChoices.includes(z))throw new X1(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(z,J);return z},this}name(){if(this.long)return this.long.replace(/^--/,"");return this.short.replace(/^-/,"")}attributeName(){return G1(this.name().replace(/^no-/,""))}is($){return this.short===$||this.long===$}isBoolean(){return!this.required&&!this.optional&&!this.negate}}class X0{constructor($){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,$.forEach((z)=>{if(z.negate)this.negativeOptions.set(z.attributeName(),z);else this.positiveOptions.set(z.attributeName(),z)}),this.negativeOptions.forEach((z,J)=>{if(this.positiveOptions.has(J))this.dualOptions.add(J)})}valueFromOption($,z){let J=z.attributeName();if(!this.dualOptions.has(J))return!0;let Q=this.negativeOptions.get(J).presetArg,Y=Q!==void 0?Q:!1;return z.negate===(Y===$)}}function G1($){return $.split("-").reduce((z,J)=>{return z+J[0].toUpperCase()+J.slice(1)})}function G0($){let z,J,Q=$.split(/[ |,]+/);if(Q.length>1&&!/^[[<]/.test(Q[1]))z=Q.shift();if(J=Q.shift(),!z&&/^-[^-]$/.test(J))z=J,J=void 0;return{shortFlag:z,longFlag:J}}W1.Option=B0;W1.splitOptionFlags=G0;W1.DualOptions=X0});var W0=j((H1)=>{function L1($,z){if(Math.abs($.length-z.length)>3)return Math.max($.length,z.length);let J=[];for(let Q=0;Q<=$.length;Q++)J[Q]=[Q];for(let Q=0;Q<=z.length;Q++)J[0][Q]=Q;for(let Q=1;Q<=z.length;Q++)for(let Y=1;Y<=$.length;Y++){let Z=1;if($[Y-1]===z[Q-1])Z=0;else Z=1;if(J[Y][Q]=Math.min(J[Y-1][Q]+1,J[Y][Q-1]+1,J[Y-1][Q-1]+Z),Y>1&&Q>1&&$[Y-1]===z[Q-2]&&$[Y-2]===z[Q-1])J[Y][Q]=Math.min(J[Y][Q],J[Y-2][Q-2]+1)}return J[$.length][z.length]}function R1($,z){if(!z||z.length===0)return"";z=Array.from(new Set(z));let J=$.startsWith("--");if(J)$=$.slice(2),z=z.map((B)=>B.slice(2));let Q=[],Y=3,Z=0.4;if(z.forEach((B)=>{if(B.length<=1)return;let q=L1($,B),X=Math.max($.length,B.length);if((X-q)/X>Z){if(q<Y)Y=q,Q=[B];else if(q===Y)Q.push(B)}}),Q.sort((B,q)=>B.localeCompare(q)),J)Q=Q.map((B)=>`--${B}`);if(Q.length>1)return`
|
|
10
|
+
(Did you mean one of ${Q.join(", ")}?)`;if(Q.length===1)return`
|
|
11
|
+
(Did you mean ${Q[0]}?)`;return""}H1.suggestSimilar=R1});var R0=j((D1)=>{var T1=V("events").EventEmitter,g=V("child_process"),R=V("path"),c=V("fs"),M=V("process"),{Argument:j1,humanReadableArgName:I1}=F(),{CommanderError:l}=N(),{Help:S1}=h(),{Option:M0,splitOptionFlags:V1,DualOptions:N1}=u(),{suggestSimilar:U0}=W0();class m extends T1{constructor($){super();this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!0,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=$||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._outputConfiguration={writeOut:(z)=>M.stdout.write(z),writeErr:(z)=>M.stderr.write(z),getOutHelpWidth:()=>M.stdout.isTTY?M.stdout.columns:void 0,getErrHelpWidth:()=>M.stderr.isTTY?M.stderr.columns:void 0,outputError:(z,J)=>J(z)},this._hidden=!1,this._hasHelpOption=!0,this._helpFlags="-h, --help",this._helpDescription="display help for command",this._helpShortFlag="-h",this._helpLongFlag="--help",this._addImplicitHelpCommand=void 0,this._helpCommandName="help",this._helpCommandnameAndArgs="help [command]",this._helpCommandDescription="display help for command",this._helpConfiguration={}}copyInheritedSettings($){return this._outputConfiguration=$._outputConfiguration,this._hasHelpOption=$._hasHelpOption,this._helpFlags=$._helpFlags,this._helpDescription=$._helpDescription,this._helpShortFlag=$._helpShortFlag,this._helpLongFlag=$._helpLongFlag,this._helpCommandName=$._helpCommandName,this._helpCommandnameAndArgs=$._helpCommandnameAndArgs,this._helpCommandDescription=$._helpCommandDescription,this._helpConfiguration=$._helpConfiguration,this._exitCallback=$._exitCallback,this._storeOptionsAsProperties=$._storeOptionsAsProperties,this._combineFlagAndOptionalValue=$._combineFlagAndOptionalValue,this._allowExcessArguments=$._allowExcessArguments,this._enablePositionalOptions=$._enablePositionalOptions,this._showHelpAfterError=$._showHelpAfterError,this._showSuggestionAfterError=$._showSuggestionAfterError,this}_getCommandAndAncestors(){let $=[];for(let z=this;z;z=z.parent)$.push(z);return $}command($,z,J){let Q=z,Y=J;if(typeof Q==="object"&&Q!==null)Y=Q,Q=null;Y=Y||{};let[,Z,B]=$.match(/([^ ]+) *(.*)/),q=this.createCommand(Z);if(Q)q.description(Q),q._executableHandler=!0;if(Y.isDefault)this._defaultCommandName=q._name;if(q._hidden=!!(Y.noHelp||Y.hidden),q._executableFile=Y.executableFile||null,B)q.arguments(B);if(this.commands.push(q),q.parent=this,q.copyInheritedSettings(this),Q)return this;return q}createCommand($){return new m($)}createHelp(){return Object.assign(new S1,this.configureHelp())}configureHelp($){if($===void 0)return this._helpConfiguration;return this._helpConfiguration=$,this}configureOutput($){if($===void 0)return this._outputConfiguration;return Object.assign(this._outputConfiguration,$),this}showHelpAfterError($=!0){if(typeof $!=="string")$=!!$;return this._showHelpAfterError=$,this}showSuggestionAfterError($=!0){return this._showSuggestionAfterError=!!$,this}addCommand($,z){if(!$._name)throw Error(`Command passed to .addCommand() must have a name
|
|
12
|
+
- specify the name in Command constructor or using .name()`);if(z=z||{},z.isDefault)this._defaultCommandName=$._name;if(z.noHelp||z.hidden)$._hidden=!0;return this.commands.push($),$.parent=this,this}createArgument($,z){return new j1($,z)}argument($,z,J,Q){let Y=this.createArgument($,z);if(typeof J==="function")Y.default(Q).argParser(J);else Y.default(J);return this.addArgument(Y),this}arguments($){return $.trim().split(/ +/).forEach((z)=>{this.argument(z)}),this}addArgument($){let z=this.registeredArguments.slice(-1)[0];if(z&&z.variadic)throw Error(`only the last argument can be variadic '${z.name()}'`);if($.required&&$.defaultValue!==void 0&&$.parseArg===void 0)throw Error(`a default value for a required argument is never used: '${$.name()}'`);return this.registeredArguments.push($),this}addHelpCommand($,z){if($===!1)this._addImplicitHelpCommand=!1;else{if(this._addImplicitHelpCommand=!0,typeof $==="string")this._helpCommandName=$.split(" ")[0],this._helpCommandnameAndArgs=$;this._helpCommandDescription=z||this._helpCommandDescription}return this}_hasImplicitHelpCommand(){if(this._addImplicitHelpCommand===void 0)return this.commands.length&&!this._actionHandler&&!this._findCommand("help");return this._addImplicitHelpCommand}hook($,z){let J=["preSubcommand","preAction","postAction"];if(!J.includes($))throw Error(`Unexpected value for event passed to hook : '${$}'.
|
|
13
|
+
Expecting one of '${J.join("', '")}'`);if(this._lifeCycleHooks[$])this._lifeCycleHooks[$].push(z);else this._lifeCycleHooks[$]=[z];return this}exitOverride($){if($)this._exitCallback=$;else this._exitCallback=(z)=>{if(z.code!=="commander.executeSubCommandAsync")throw z};return this}_exit($,z,J){if(this._exitCallback)this._exitCallback(new l($,z,J));M.exit($)}action($){let z=(J)=>{let Q=this.registeredArguments.length,Y=J.slice(0,Q);if(this._storeOptionsAsProperties)Y[Q]=this;else Y[Q]=this.opts();return Y.push(this),$.apply(this,Y)};return this._actionHandler=z,this}createOption($,z){return new M0($,z)}_callParseArg($,z,J,Q){try{return $.parseArg(z,J)}catch(Y){if(Y.code==="commander.invalidArgument"){let Z=`${Q} ${Y.message}`;this.error(Z,{exitCode:Y.exitCode,code:Y.code})}throw Y}}addOption($){let z=$.name(),J=$.attributeName();if($.negate){let Y=$.long.replace(/^--no-/,"--");if(!this._findOption(Y))this.setOptionValueWithSource(J,$.defaultValue===void 0?!0:$.defaultValue,"default")}else if($.defaultValue!==void 0)this.setOptionValueWithSource(J,$.defaultValue,"default");this.options.push($);let Q=(Y,Z,B)=>{if(Y==null&&$.presetArg!==void 0)Y=$.presetArg;let q=this.getOptionValue(J);if(Y!==null&&$.parseArg)Y=this._callParseArg($,Y,q,Z);else if(Y!==null&&$.variadic)Y=$._concatValue(Y,q);if(Y==null)if($.negate)Y=!1;else if($.isBoolean()||$.optional)Y=!0;else Y="";this.setOptionValueWithSource(J,Y,B)};if(this.on("option:"+z,(Y)=>{let Z=`error: option '${$.flags}' argument '${Y}' is invalid.`;Q(Y,Z,"cli")}),$.envVar)this.on("optionEnv:"+z,(Y)=>{let Z=`error: option '${$.flags}' value '${Y}' from env '${$.envVar}' is invalid.`;Q(Y,Z,"env")});return this}_optionEx($,z,J,Q,Y){if(typeof z==="object"&&z instanceof M0)throw Error("To add an Option object use addOption() instead of option() or requiredOption()");let Z=this.createOption(z,J);if(Z.makeOptionMandatory(!!$.mandatory),typeof Q==="function")Z.default(Y).argParser(Q);else if(Q instanceof RegExp){let B=Q;Q=(q,X)=>{let G=B.exec(q);return G?G[0]:X},Z.default(Y).argParser(Q)}else Z.default(Q);return this.addOption(Z)}option($,z,J,Q){return this._optionEx({},$,z,J,Q)}requiredOption($,z,J,Q){return this._optionEx({mandatory:!0},$,z,J,Q)}combineFlagAndOptionalValue($=!0){return this._combineFlagAndOptionalValue=!!$,this}allowUnknownOption($=!0){return this._allowUnknownOption=!!$,this}allowExcessArguments($=!0){return this._allowExcessArguments=!!$,this}enablePositionalOptions($=!0){return this._enablePositionalOptions=!!$,this}passThroughOptions($=!0){if(this._passThroughOptions=!!$,!!this.parent&&$&&!this.parent._enablePositionalOptions)throw Error("passThroughOptions can not be used without turning on enablePositionalOptions for parent command(s)");return this}storeOptionsAsProperties($=!0){if(this.options.length)throw Error("call .storeOptionsAsProperties() before adding options");return this._storeOptionsAsProperties=!!$,this}getOptionValue($){if(this._storeOptionsAsProperties)return this[$];return this._optionValues[$]}setOptionValue($,z){return this.setOptionValueWithSource($,z,void 0)}setOptionValueWithSource($,z,J){if(this._storeOptionsAsProperties)this[$]=z;else this._optionValues[$]=z;return this._optionValueSources[$]=J,this}getOptionValueSource($){return this._optionValueSources[$]}getOptionValueSourceWithGlobals($){let z;return this._getCommandAndAncestors().forEach((J)=>{if(J.getOptionValueSource($)!==void 0)z=J.getOptionValueSource($)}),z}_prepareUserArgs($,z){if($!==void 0&&!Array.isArray($))throw Error("first parameter to parse must be array or undefined");if(z=z||{},$===void 0){if($=M.argv,M.versions&&M.versions.electron)z.from="electron"}this.rawArgs=$.slice();let J;switch(z.from){case void 0:case"node":this._scriptPath=$[1],J=$.slice(2);break;case"electron":if(M.defaultApp)this._scriptPath=$[1],J=$.slice(2);else J=$.slice(1);break;case"user":J=$.slice(0);break;default:throw Error(`unexpected parse option { from: '${z.from}' }`)}if(!this._name&&this._scriptPath)this.nameFromFilename(this._scriptPath);return this._name=this._name||"program",J}parse($,z){let J=this._prepareUserArgs($,z);return this._parseCommand([],J),this}async parseAsync($,z){let J=this._prepareUserArgs($,z);return await this._parseCommand([],J),this}_executeSubCommand($,z){z=z.slice();let J=!1,Q=[".js",".ts",".tsx",".mjs",".cjs"];function Y(G,W){let K=R.resolve(G,W);if(c.existsSync(K))return K;if(Q.includes(R.extname(W)))return;let T=Q.find((U)=>c.existsSync(`${K}${U}`));if(T)return`${K}${T}`;return}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let Z=$._executableFile||`${this._name}-${$._name}`,B=this._executableDir||"";if(this._scriptPath){let G;try{G=c.realpathSync(this._scriptPath)}catch(W){G=this._scriptPath}B=R.resolve(R.dirname(G),B)}if(B){let G=Y(B,Z);if(!G&&!$._executableFile&&this._scriptPath){let W=R.basename(this._scriptPath,R.extname(this._scriptPath));if(W!==this._name)G=Y(B,`${W}-${$._name}`)}Z=G||Z}J=Q.includes(R.extname(Z));let q;if(M.platform!=="win32")if(J)z.unshift(Z),z=L0(M.execArgv).concat(z),q=g.spawn(M.argv[0],z,{stdio:"inherit"});else q=g.spawn(Z,z,{stdio:"inherit"});else z.unshift(Z),z=L0(M.execArgv).concat(z),q=g.spawn(M.execPath,z,{stdio:"inherit"});if(!q.killed)["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach((W)=>{M.on(W,()=>{if(q.killed===!1&&q.exitCode===null)q.kill(W)})});let X=this._exitCallback;if(!X)q.on("close",M.exit.bind(M));else q.on("close",()=>{X(new l(M.exitCode||0,"commander.executeSubCommandAsync","(close)"))});q.on("error",(G)=>{if(G.code==="ENOENT"){let W=B?`searched for local subcommand relative to directory '${B}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",K=`'${Z}' does not exist
|
|
14
|
+
- if '${$._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
15
|
+
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
|
16
|
+
- ${W}`;throw Error(K)}else if(G.code==="EACCES")throw Error(`'${Z}' not executable`);if(!X)M.exit(1);else{let W=new l(1,"commander.executeSubCommandAsync","(error)");W.nestedError=G,X(W)}}),this.runningCommand=q}_dispatchSubcommand($,z,J){let Q=this._findCommand($);if(!Q)this.help({error:!0});let Y;return Y=this._chainOrCallSubCommandHook(Y,Q,"preSubcommand"),Y=this._chainOrCall(Y,()=>{if(Q._executableHandler)this._executeSubCommand(Q,z.concat(J));else return Q._parseCommand(z,J)}),Y}_dispatchHelpCommand($){if(!$)this.help();let z=this._findCommand($);if(z&&!z._executableHandler)z.help();return this._dispatchSubcommand($,[],[this._helpLongFlag||this._helpShortFlag])}_checkNumberOfArguments(){if(this.registeredArguments.forEach(($,z)=>{if($.required&&this.args[z]==null)this.missingArgument($.name())}),this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)return;if(this.args.length>this.registeredArguments.length)this._excessArguments(this.args)}_processArguments(){let $=(J,Q,Y)=>{let Z=Q;if(Q!==null&&J.parseArg){let B=`error: command-argument value '${Q}' is invalid for argument '${J.name()}'.`;Z=this._callParseArg(J,Q,Y,B)}return Z};this._checkNumberOfArguments();let z=[];this.registeredArguments.forEach((J,Q)=>{let Y=J.defaultValue;if(J.variadic){if(Q<this.args.length){if(Y=this.args.slice(Q),J.parseArg)Y=Y.reduce((Z,B)=>{return $(J,B,Z)},J.defaultValue)}else if(Y===void 0)Y=[]}else if(Q<this.args.length){if(Y=this.args[Q],J.parseArg)Y=$(J,Y,J.defaultValue)}z[Q]=Y}),this.processedArgs=z}_chainOrCall($,z){if($&&$.then&&typeof $.then==="function")return $.then(()=>z());return z()}_chainOrCallHooks($,z){let J=$,Q=[];if(this._getCommandAndAncestors().reverse().filter((Y)=>Y._lifeCycleHooks[z]!==void 0).forEach((Y)=>{Y._lifeCycleHooks[z].forEach((Z)=>{Q.push({hookedCommand:Y,callback:Z})})}),z==="postAction")Q.reverse();return Q.forEach((Y)=>{J=this._chainOrCall(J,()=>{return Y.callback(Y.hookedCommand,this)})}),J}_chainOrCallSubCommandHook($,z,J){let Q=$;if(this._lifeCycleHooks[J]!==void 0)this._lifeCycleHooks[J].forEach((Y)=>{Q=this._chainOrCall(Q,()=>{return Y(this,z)})});return Q}_parseCommand($,z){let J=this.parseOptions(z);if(this._parseOptionsEnv(),this._parseOptionsImplied(),$=$.concat(J.operands),z=J.unknown,this.args=$.concat(z),$&&this._findCommand($[0]))return this._dispatchSubcommand($[0],$.slice(1),z);if(this._hasImplicitHelpCommand()&&$[0]===this._helpCommandName)return this._dispatchHelpCommand($[1]);if(this._defaultCommandName)return K0(this,z),this._dispatchSubcommand(this._defaultCommandName,$,z);if(this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName)this.help({error:!0});K0(this,J.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let Q=()=>{if(J.unknown.length>0)this.unknownOption(J.unknown[0])},Y=`command:${this.name()}`;if(this._actionHandler){Q(),this._processArguments();let Z;if(Z=this._chainOrCallHooks(Z,"preAction"),Z=this._chainOrCall(Z,()=>this._actionHandler(this.processedArgs)),this.parent)Z=this._chainOrCall(Z,()=>{this.parent.emit(Y,$,z)});return Z=this._chainOrCallHooks(Z,"postAction"),Z}if(this.parent&&this.parent.listenerCount(Y))Q(),this._processArguments(),this.parent.emit(Y,$,z);else if($.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",$,z);if(this.listenerCount("command:*"))this.emit("command:*",$,z);else if(this.commands.length)this.unknownCommand();else Q(),this._processArguments()}else if(this.commands.length)Q(),this.help({error:!0});else Q(),this._processArguments()}_findCommand($){if(!$)return;return this.commands.find((z)=>z._name===$||z._aliases.includes($))}_findOption($){return this.options.find((z)=>z.is($))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(($)=>{$.options.forEach((z)=>{if(z.mandatory&&$.getOptionValue(z.attributeName())===void 0)$.missingMandatoryOptionValue(z)})})}_checkForConflictingLocalOptions(){let $=this.options.filter((J)=>{let Q=J.attributeName();if(this.getOptionValue(Q)===void 0)return!1;return this.getOptionValueSource(Q)!=="default"});$.filter((J)=>J.conflictsWith.length>0).forEach((J)=>{let Q=$.find((Y)=>J.conflictsWith.includes(Y.attributeName()));if(Q)this._conflictingOption(J,Q)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(($)=>{$._checkForConflictingLocalOptions()})}parseOptions($){let z=[],J=[],Q=z,Y=$.slice();function Z(q){return q.length>1&&q[0]==="-"}let B=null;while(Y.length){let q=Y.shift();if(q==="--"){if(Q===J)Q.push(q);Q.push(...Y);break}if(B&&!Z(q)){this.emit(`option:${B.name()}`,q);continue}if(B=null,Z(q)){let X=this._findOption(q);if(X){if(X.required){let G=Y.shift();if(G===void 0)this.optionMissingArgument(X);this.emit(`option:${X.name()}`,G)}else if(X.optional){let G=null;if(Y.length>0&&!Z(Y[0]))G=Y.shift();this.emit(`option:${X.name()}`,G)}else this.emit(`option:${X.name()}`);B=X.variadic?X:null;continue}}if(q.length>2&&q[0]==="-"&&q[1]!=="-"){let X=this._findOption(`-${q[1]}`);if(X){if(X.required||X.optional&&this._combineFlagAndOptionalValue)this.emit(`option:${X.name()}`,q.slice(2));else this.emit(`option:${X.name()}`),Y.unshift(`-${q.slice(2)}`);continue}}if(/^--[^=]+=/.test(q)){let X=q.indexOf("="),G=this._findOption(q.slice(0,X));if(G&&(G.required||G.optional)){this.emit(`option:${G.name()}`,q.slice(X+1));continue}}if(Z(q))Q=J;if((this._enablePositionalOptions||this._passThroughOptions)&&z.length===0&&J.length===0){if(this._findCommand(q)){if(z.push(q),Y.length>0)J.push(...Y);break}else if(q===this._helpCommandName&&this._hasImplicitHelpCommand()){if(z.push(q),Y.length>0)z.push(...Y);break}else if(this._defaultCommandName){if(J.push(q),Y.length>0)J.push(...Y);break}}if(this._passThroughOptions){if(Q.push(q),Y.length>0)Q.push(...Y);break}Q.push(q)}return{operands:z,unknown:J}}opts(){if(this._storeOptionsAsProperties){let $={},z=this.options.length;for(let J=0;J<z;J++){let Q=this.options[J].attributeName();$[Q]=Q===this._versionOptionName?this._version:this[Q]}return $}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce(($,z)=>Object.assign($,z.opts()),{})}error($,z){if(this._outputConfiguration.outputError(`${$}
|
|
17
|
+
`,this._outputConfiguration.writeErr),typeof this._showHelpAfterError==="string")this._outputConfiguration.writeErr(`${this._showHelpAfterError}
|
|
18
|
+
`);else if(this._showHelpAfterError)this._outputConfiguration.writeErr(`
|
|
19
|
+
`),this.outputHelp({error:!0});let J=z||{},Q=J.exitCode||1,Y=J.code||"commander.error";this._exit(Q,Y,$)}_parseOptionsEnv(){this.options.forEach(($)=>{if($.envVar&&$.envVar in M.env){let z=$.attributeName();if(this.getOptionValue(z)===void 0||["default","config","env"].includes(this.getOptionValueSource(z)))if($.required||$.optional)this.emit(`optionEnv:${$.name()}`,M.env[$.envVar]);else this.emit(`optionEnv:${$.name()}`)}})}_parseOptionsImplied(){let $=new N1(this.options),z=(J)=>{return this.getOptionValue(J)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(J))};this.options.filter((J)=>J.implied!==void 0&&z(J.attributeName())&&$.valueFromOption(this.getOptionValue(J.attributeName()),J)).forEach((J)=>{Object.keys(J.implied).filter((Q)=>!z(Q)).forEach((Q)=>{this.setOptionValueWithSource(Q,J.implied[Q],"implied")})})}missingArgument($){let z=`error: missing required argument '${$}'`;this.error(z,{code:"commander.missingArgument"})}optionMissingArgument($){let z=`error: option '${$.flags}' argument missing`;this.error(z,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue($){let z=`error: required option '${$.flags}' not specified`;this.error(z,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption($,z){let J=(Z)=>{let B=Z.attributeName(),q=this.getOptionValue(B),X=this.options.find((W)=>W.negate&&B===W.attributeName()),G=this.options.find((W)=>!W.negate&&B===W.attributeName());if(X&&(X.presetArg===void 0&&q===!1||X.presetArg!==void 0&&q===X.presetArg))return X;return G||Z},Q=(Z)=>{let B=J(Z),q=B.attributeName();if(this.getOptionValueSource(q)==="env")return`environment variable '${B.envVar}'`;return`option '${B.flags}'`},Y=`error: ${Q($)} cannot be used with ${Q(z)}`;this.error(Y,{code:"commander.conflictingOption"})}unknownOption($){if(this._allowUnknownOption)return;let z="";if($.startsWith("--")&&this._showSuggestionAfterError){let Q=[],Y=this;do{let Z=Y.createHelp().visibleOptions(Y).filter((B)=>B.long).map((B)=>B.long);Q=Q.concat(Z),Y=Y.parent}while(Y&&!Y._enablePositionalOptions);z=U0($,Q)}let J=`error: unknown option '${$}'${z}`;this.error(J,{code:"commander.unknownOption"})}_excessArguments($){if(this._allowExcessArguments)return;let z=this.registeredArguments.length,J=z===1?"":"s",Y=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${z} argument${J} but got ${$.length}.`;this.error(Y,{code:"commander.excessArguments"})}unknownCommand(){let $=this.args[0],z="";if(this._showSuggestionAfterError){let Q=[];this.createHelp().visibleCommands(this).forEach((Y)=>{if(Q.push(Y.name()),Y.alias())Q.push(Y.alias())}),z=U0($,Q)}let J=`error: unknown command '${$}'${z}`;this.error(J,{code:"commander.unknownCommand"})}version($,z,J){if($===void 0)return this._version;this._version=$,z=z||"-V, --version",J=J||"output the version number";let Q=this.createOption(z,J);return this._versionOptionName=Q.attributeName(),this.options.push(Q),this.on("option:"+Q.name(),()=>{this._outputConfiguration.writeOut(`${$}
|
|
20
|
+
`),this._exit(0,"commander.version",$)}),this}description($,z){if($===void 0&&z===void 0)return this._description;if(this._description=$,z)this._argsDescription=z;return this}summary($){if($===void 0)return this._summary;return this._summary=$,this}alias($){if($===void 0)return this._aliases[0];let z=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)z=this.commands[this.commands.length-1];if($===z._name)throw Error("Command alias can't be the same as its name");return z._aliases.push($),this}aliases($){if($===void 0)return this._aliases;return $.forEach((z)=>this.alias(z)),this}usage($){if($===void 0){if(this._usage)return this._usage;let z=this.registeredArguments.map((J)=>{return I1(J)});return[].concat(this.options.length||this._hasHelpOption?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?z:[]).join(" ")}return this._usage=$,this}name($){if($===void 0)return this._name;return this._name=$,this}nameFromFilename($){return this._name=R.basename($,R.extname($)),this}executableDir($){if($===void 0)return this._executableDir;return this._executableDir=$,this}helpInformation($){let z=this.createHelp();if(z.helpWidth===void 0)z.helpWidth=$&&$.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth();return z.formatHelp(this,z)}_getHelpContext($){$=$||{};let z={error:!!$.error},J;if(z.error)J=(Q)=>this._outputConfiguration.writeErr(Q);else J=(Q)=>this._outputConfiguration.writeOut(Q);return z.write=$.write||J,z.command=this,z}outputHelp($){let z;if(typeof $==="function")z=$,$=void 0;let J=this._getHelpContext($);this._getCommandAndAncestors().reverse().forEach((Y)=>Y.emit("beforeAllHelp",J)),this.emit("beforeHelp",J);let Q=this.helpInformation(J);if(z){if(Q=z(Q),typeof Q!=="string"&&!Buffer.isBuffer(Q))throw Error("outputHelp callback must return a string or a Buffer")}if(J.write(Q),this._helpLongFlag)this.emit(this._helpLongFlag);this.emit("afterHelp",J),this._getCommandAndAncestors().forEach((Y)=>Y.emit("afterAllHelp",J))}helpOption($,z){if(typeof $==="boolean")return this._hasHelpOption=$,this;this._helpFlags=$||this._helpFlags,this._helpDescription=z||this._helpDescription;let J=V1(this._helpFlags);return this._helpShortFlag=J.shortFlag,this._helpLongFlag=J.longFlag,this}help($){this.outputHelp($);let z=M.exitCode||0;if(z===0&&$&&typeof $!=="function"&&$.error)z=1;this._exit(z,"commander.help","(outputHelp)")}addHelpText($,z){let J=["beforeAll","before","after","afterAll"];if(!J.includes($))throw Error(`Unexpected value for position to addHelpText.
|
|
21
|
+
Expecting one of '${J.join("', '")}'`);let Q=`${$}Help`;return this.on(Q,(Y)=>{let Z;if(typeof z==="function")Z=z({error:Y.error,command:Y.command});else Z=z;if(Z)Y.write(`${Z}
|
|
22
|
+
`)}),this}}function K0($,z){if($._hasHelpOption&&z.find((Q)=>Q===$._helpLongFlag||Q===$._helpShortFlag))$.outputHelp(),$._exit(0,"commander.helpDisplayed","(outputHelp)")}function L0($){return $.map((z)=>{if(!z.startsWith("--inspect"))return z;let J,Q="127.0.0.1",Y="9229",Z;if((Z=z.match(/^(--inspect(-brk)?)$/))!==null)J=Z[1];else if((Z=z.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(J=Z[1],/^\d+$/.test(Z[3]))Y=Z[3];else Q=Z[3];else if((Z=z.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)J=Z[1],Q=Z[3],Y=Z[4];if(J&&Y!=="0")return`${J}=${Q}:${parseInt(Y)+1}`;return z})}D1.Command=m});var j0=j((L,T0)=>{var{Argument:E1}=F(),{Command:H0}=R0(),{CommanderError:F1,InvalidArgumentError:_0}=N(),{Help:w1}=h(),{Option:k1}=u();L=T0.exports=new H0;L.program=L;L.Command=H0;L.Option=k1;L.Argument=E1;L.Help=w1;L.CommanderError=F1;L.InvalidArgumentError=_0;L.InvalidOptionArgumentError=_0});import{execFileSync as X$}from"node:child_process";var I0=o0(j0(),1),{program:_$,createCommand:T$,createArgument:j$,createOption:I$,CommanderError:S$,InvalidArgumentError:V$,InvalidOptionArgumentError:N$,Command:S0,Argument:D$,Option:P$,Help:E$}=I0.default;import y1 from"node:os";import S from"node:path";import d from"node:fs/promises";var A1="https://ingest.agentsoc.com/api/v1/webhooks/syslog",C1="http://localhost:8110/api/v1/webhooks/syslog",b1="https://api.agentsoc.com",f1="http://localhost:8100",O1="/api/v1/siem/beacon/validate/key";function s($){let z=process.env.AGENTSOC_API_KEY?.trim();if(z)return z;return $.apiKey?.trim()||void 0}var D="Beacon is not configured. Run: beacon config --key <your-api-key> [--env production|development]. Or set AGENTSOC_API_KEY in your environment.";function w($){let z=$.toLowerCase().trim();if(z==="production"||z==="prod")return"production";if(z==="development"||z==="dev")return"development";throw Error(`Invalid environment "${$}". Use production or development (prod / dev).`)}function i($){if($==="production"||$==="development")return $;if(typeof $==="string")try{return w($)}catch{return}return}function x1($){return $==="development"?C1:A1}function v1($){return $==="development"?f1:b1}function h1(){let $=process.env.AGENTSOC_ENV?.trim();if(!$)return;try{return w($)}catch{console.warn(`[beacon] Ignoring invalid AGENTSOC_ENV="${$}" (use production or development).`);return}}function V0($){return h1()??i($.environment)??"production"}function N0($){let z=process.env.AGENTSOC_INGEST_URL?.trim();if(z)return z;return x1(V0($))}function u1($){let z=process.env.AGENTSOC_PLATFORM_URL?.trim()||process.env.AGENTSOC_PLATFORM_API_BASE_URL?.trim();if(z)return z.replace(/\/$/,"");return v1(V0($))}function D0($){return`${u1($)}${O1}`}function k(){let $=y1.homedir();if(process.platform==="win32")return S.join(process.env.APPDATA||S.join($,"AppData","Roaming"),"agentsoc-beacon");if(process.platform==="darwin")return S.join($,"Library","Application Support","agentsoc-beacon");let z=process.env.XDG_CONFIG_HOME||S.join($,".config");return S.join(z,"agentsoc-beacon")}function p(){return S.join(k(),"config.json")}async function _(){try{let $=p(),z=await d.readFile($,"utf8");return JSON.parse(z)}catch($){return{}}}async function y($){let z=k();try{await d.mkdir(z,{recursive:!0}),await d.writeFile(p(),JSON.stringify($,null,2),"utf8")}catch(J){console.error(`[syslog-beacon] Failed to save config to ${p()}:`,J)}}async function P0($,z){let J=new AbortController,Q=setTimeout(()=>J.abort(),12000);try{let Y=await fetch($,{method:"GET",headers:{"X-API-Key":z},signal:J.signal}),Z=await Y.text(),B;try{B=Z?JSON.parse(Z):null}catch{return{ok:!1,message:"Invalid response from platform API"}}if(!Y.ok){let X=B;return{ok:!1,message:X&&typeof X.error==="string"?X.error:`HTTP ${Y.status}`}}let q=B;if(!q?.success||!q.apiKey?.name)return{ok:!1,message:"Unexpected response from platform API"};return{ok:!0,organizationName:q.organization?.name??null,organizationSlug:q.organization?.slug??null,apiKeyName:q.apiKey.name}}catch(Y){if(Y instanceof Error&&Y.name==="AbortError")return{ok:!1,message:"Request timed out"};return{ok:!1,message:Y instanceof Error?Y.message:String(Y)}}finally{clearTimeout(Q)}}var g1=`https://registry.npmjs.org/${encodeURIComponent("@agentsoc/beacon")}`;function c1($,z){return{success:!0,package:"@agentsoc/beacon",latestVersion:$,registryResolved:z,install:{npm:"npm install -g @agentsoc/beacon@latest",bun:"bun add -g @agentsoc/beacon@latest",pnpm:"pnpm add -g @agentsoc/beacon@latest"},docsUrl:"https://agentsoc.com/products/agentsoc-beacon",installScriptUrl:"https://agentsoc.com/connectors/beacon.sh"}}async function E0(){let $=new AbortController,z=setTimeout(()=>$.abort(),12000);try{let J=await fetch(g1,{headers:{Accept:"application/json"},signal:$.signal}),Q=await J.text(),Y;try{Y=Q?JSON.parse(Q):null}catch{return{ok:!1,message:"Invalid JSON from registry.npmjs.org"}}if(!J.ok)return{ok:!1,message:`registry.npmjs.org returned HTTP ${J.status}`};let B=Y["dist-tags"]?.latest?.trim()??null;return{ok:!0,info:c1(B,!0)}}catch(J){if(J instanceof Error&&J.name==="AbortError")return{ok:!1,message:"Request timed out"};return{ok:!1,message:J instanceof Error?J.message:String(J)}}finally{clearTimeout(z)}}import{existsSync as l1,readFileSync as m1}from"node:fs";import{dirname as F0,join as d1}from"node:path";import{fileURLToPath as p1}from"node:url";function k0(){let $=F0(p1(import.meta.url));for(let z=0;z<8;z++){let J=d1($,"package.json");if(l1(J))try{let Y=JSON.parse(m1(J,"utf8"));if(Y.name==="@agentsoc/beacon"&&typeof Y.version==="string")return Y.version}catch{}let Q=F0($);if(Q===$)break;$=Q}return"0.0.0"}function w0($){let z=$.indexOf("-");return z===-1?$:$.slice(0,z)}function n($,z){let J=w0($).split(".").map((Z)=>parseInt(Z,10)||0),Q=w0(z).split(".").map((Z)=>parseInt(Z,10)||0),Y=Math.max(J.length,Q.length);for(let Z=0;Z<Y;Z++){let B=J[Z]??0,q=Q[Z]??0;if(B<q)return!0;if(B>q)return!1}return!1}import o from"node:os";import s1 from"node:crypto";async function y0(){let $=await _(),z=$.agentId;if(!z)z=s1.randomUUID(),$.agentId=z,await y($);let J=o.hostname(),Q=o.platform(),Y="127.0.0.1",Z="00:00:00:00:00:00",B=o.networkInterfaces();for(let q of Object.keys(B)){let X=B[q];if(!X)continue;for(let G of X)if(!G.internal&&G.family==="IPv4"){Y=G.address,Z=G.mac;break}if(Y!=="127.0.0.1")break}return{agentId:z,hostname:J,ip:Y,osPlatform:Q,mac:Z}}import A from"node:fs/promises";import A0 from"node:path";var P=1,r=()=>({version:P,updatedAt:new Date(0).toISOString(),logsForwarded:0,batchesSucceeded:0,batchesFailed:0});function C(){return A0.join(k(),"stats.json")}async function b(){try{let $=await A.readFile(C(),"utf8"),z=JSON.parse($);if(z.version!==P)return r();return{...r(),...z,version:P}}catch{return r()}}async function C0($){let z=C(),J=A0.dirname(z);await A.mkdir(J,{recursive:!0});let Q=`${z}.${process.pid}.tmp`;await A.writeFile(Q,JSON.stringify($,null,2),"utf8"),await A.rename(Q,z)}async function b0($){try{let z=await b();await C0({version:P,updatedAt:new Date().toISOString(),logsForwarded:z.logsForwarded+$,batchesSucceeded:z.batchesSucceeded+1,batchesFailed:z.batchesFailed,lastError:void 0})}catch{}}async function t($){try{let z=await b(),J=$.replace(/\s+/g," ").slice(0,500);await C0({version:P,updatedAt:new Date().toISOString(),logsForwarded:z.logsForwarded,batchesSucceeded:z.batchesSucceeded,batchesFailed:z.batchesFailed+1,lastError:J||"Unknown error"})}catch{}}function i1($){let z=5,J=1,Q=$.match(/^<(\d+)>/);if(Q){let Z=parseInt(Q[1],10);J=Math.floor(Z/8),z=Z&7}else{let Z=$.toLowerCase();if(Z.includes("critical")||Z.includes("fatal")||Z.includes("panic"))z=2;else if(Z.includes("high")||Z.includes("error")||Z.includes("failed"))z=3;else if(Z.includes("medium")||Z.includes("warn"))z=4;else if(Z.includes("info"))z=6;else if(Z.includes("low")||Z.includes("notice"))z=5}let Y="info";if(z<=2)Y="critical";else if(z===3)Y="high";else if(z===4)Y="medium";else if(z===5)Y="low";return{severityStr:Y,facility:J}}function n1($){let z=$.match(/^\S+\s+(?:\S+\s+)?(\w+)(?:\[\d+\])?:\s*(.*)$/);if(z)return{app:z[1],message:z[2]};return{message:$}}class a{opts;buffer=[];timer=null;batchSize;flushMs;constructor($){this.opts=$;this.batchSize=$.batchSize||25,this.flushMs=$.flushMs||2000}pushLog($){let{severityStr:z,facility:J}=i1($),{app:Q,message:Y}=n1($),Z={full_log:Y,timestamp:new Date().toISOString(),hostname:this.opts.host.hostname,facility:J,severity:z,id:`${this.opts.host.agentId}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,agent:{id:this.opts.host.agentId,name:this.opts.host.hostname,ip:this.opts.host.ip,mac:this.opts.host.mac}};if(Q)Z.app=Q,Z.process={name:Q};if(this.buffer.push(Z),this.buffer.length>=this.batchSize)this.flush();else if(!this.timer)this.timer=setTimeout(()=>this.flush(),this.flushMs)}async flush(){if(this.timer)clearTimeout(this.timer),this.timer=null;if(this.buffer.length===0)return;let $=this.buffer;this.buffer=[],console.log(`[syslog-beacon] Pushing ${$.length} logs to API...`);try{let z=await fetch(this.opts.ingestUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.opts.apiKey}`},body:JSON.stringify($)});if(!z.ok){let J=await z.text(),Q=`HTTP ${z.status} ${J}`;console.error(`[syslog-beacon] Failed to push logs: HTTP ${z.status} ${J}`),await t(Q)}else console.log(`[syslog-beacon] Successfully pushed ${$.length} logs`),await b0($.length)}catch(z){console.error("[syslog-beacon] Ingest error:",z),await t(z instanceof Error?z.message:String(z))}}async stop(){if(this.buffer.length>0)await this.flush()}}import{spawn as e,spawnSync as o1}from"node:child_process";import r1 from"node:dgram";import f0 from"node:fs";var t1=["/var/log/syslog","/var/log/auth.log","/var/log/messages"];function a1(){return t1.filter(($)=>{try{return f0.existsSync($)&&f0.statSync($).isFile()}catch{return!1}})}function e1(){let $=o1("journalctl",["--version"],{stdio:"ignore"});return!$.error&&$.status===0}var $$=/not seeing messages from other users/i;class $0{onLog;tailProc;udpServer;journalRestrictedHintShown=!1;constructor($){this.onLog=$}startUdpListener(){this.udpServer=r1.createSocket("udp4"),this.udpServer.on("message",($)=>{this.onLog($.toString("utf8").trim())}),this.udpServer.on("error",($)=>{console.error(`[syslog-udp] error:
|
|
23
|
+
${$.stack}`),this.udpServer?.close()}),this.udpServer.bind(5140,()=>{console.log("[syslog-udp] listening on UDP 5140")})}start(){if(process.platform==="linux"){let $=!1;if(e1())$=!0,console.log("[syslog-tail] Streaming systemd journal (journalctl -f)"),this.tailProc=e("journalctl",["-f","--no-pager","-o","short-iso"]);else{let z=a1();if(z.length>0)console.log(`[syslog-tail] Following: ${z.join(", ")}`),this.tailProc=e("tail",["-F",...z]);else{console.log("[syslog-tail] No journalctl or log files under /var/log; listening on UDP 5140"),this.startUdpListener();return}}this.tailProc.stdout?.on("data",(z)=>{let J=z.toString().split(`
|
|
24
|
+
`);for(let Q of J)if(Q.trim())this.onLog(Q)}),this.tailProc.stderr?.on("data",(z)=>{let J=z.toString();if(console.error(`[syslog-tail] ${J}`),$&&!this.journalRestrictedHintShown&&$$.test(J))this.journalRestrictedHintShown=!0,console.error("[syslog-tail] Only your user journal is visible. For system-wide logs, add this user to group systemd-journal or adm, or run beacon as root (no extra packages).")})}else if(process.platform==="darwin")this.tailProc=e("log",["stream","--predicate",'process == "sshd" or process == "sudo" or process == "login" or process == "logger"',"--style","syslog"]),console.log("[syslog-tail] macOS log stream started"),this.tailProc.stdout?.on("data",($)=>{let z=$.toString().split(`
|
|
25
|
+
`);for(let J of z)if(J.trim())this.onLog(J)}),this.tailProc.stderr?.on("data",($)=>{console.error(`[syslog-tail] ${$.toString()}`)});else this.startUdpListener()}stop(){if(this.tailProc)this.tailProc.kill();if(this.udpServer)this.udpServer.close()}}async function O0($){let z=await y0(),J=new a({...$,host:z}),Q=new $0((Y)=>{J.pushLog(Y)});return Q.start(),{stop:async()=>{Q.stop(),await J.stop()}}}import{constants as z$}from"node:fs";import J0 from"node:fs/promises";import J$ from"node:os";import f from"node:path";import{execFileSync as E,execSync as z0}from"node:child_process";var Q$=`That location is only writable as root. Run the same command with sudo, for example:
|
|
26
|
+
|
|
27
|
+
sudo beacon install
|
|
28
|
+
|
|
29
|
+
You will be prompted for your administrator password.`;function u0($){return Error(`Cannot install the system service: permission denied for ${f.dirname($)}.
|
|
30
|
+
|
|
31
|
+
${Q$}`)}async function x0($){let z=f.dirname($);try{await J0.access(z,z$.W_OK)}catch(J){let Q=J&&typeof J==="object"&&"code"in J?J.code:void 0;if(Q==="EACCES"||Q==="EPERM")throw u0($);throw J}}async function v0($,z){try{await J0.writeFile($,z,"utf8")}catch(J){let Q=J&&typeof J==="object"&&"code"in J?J.code:void 0;if(Q==="EACCES"||Q==="EPERM")throw u0($);throw J}}function Y$(){if(process.execPath.endsWith("bun")||process.execPath.endsWith("bun.exe"))return process.execPath;let z=f.basename(process.execPath);if(/^node(\.exe)?$/i.test(z))return process.execPath;try{let J=E("/usr/bin/which",["node"],{encoding:"utf8"}).trim();if(J)return J}catch{}return"node"}function Z$($,z){try{E("launchctl",["bootout","system",$],{stdio:"ignore"});return}catch{}try{E("launchctl",["bootout",`system/${z}`],{stdio:"ignore"})}catch{}}function h0(){let $=process.env.SUDO_USER?.trim();if($)return $;if((typeof process.getuid==="function"?process.getuid():-1)!==0)try{return J$.userInfo().username}catch{}throw Error("Cannot determine which user account should run the beacon daemon. Config is stored under that user's home directory. Run install from your normal account with sudo, e.g. `sudo beacon install`, not from a root-only shell.")}function q$($){return $.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function B$($){try{E("launchctl",["bootstrap","system",$],{encoding:"utf8",stdio:["ignore","inherit","pipe"]})}catch(z){let Q=z.stderr?.toString("utf8").trim()??"",Y=Q?`
|
|
32
|
+
${Q}`:"";throw Error(`launchctl bootstrap failed for ${$}.${Y}
|
|
33
|
+
|
|
34
|
+
Try:
|
|
35
|
+
sudo launchctl bootout system ${$}
|
|
36
|
+
sudo beacon install`)}}async function g0(){if(!(await _()).apiKey?.trim())throw Error(D);let J=process.execPath.endsWith("bun")||process.execPath.endsWith("bun.exe")?process.execPath:"node",Q=f.resolve(process.argv[1]),Y=`${J} ${Q} run`;if(process.platform==="linux"){let B=`[Unit]
|
|
37
|
+
Description=AgentSOC Syslog Beacon
|
|
38
|
+
After=network.target
|
|
39
|
+
|
|
40
|
+
[Service]
|
|
41
|
+
Type=simple
|
|
42
|
+
User=${h0()}
|
|
43
|
+
ExecStart=${Y}
|
|
44
|
+
Restart=always
|
|
45
|
+
RestartSec=10
|
|
46
|
+
Environment=NODE_ENV=production
|
|
47
|
+
|
|
48
|
+
[Install]
|
|
49
|
+
WantedBy=multi-user.target
|
|
50
|
+
`,q="/etc/systemd/system/syslog-beacon.service";await x0("/etc/systemd/system/syslog-beacon.service"),await v0("/etc/systemd/system/syslog-beacon.service",B),z0("systemctl daemon-reload"),z0("systemctl enable syslog-beacon"),z0("systemctl start syslog-beacon"),console.log("[syslog-beacon] Installed systemd service")}else if(process.platform==="darwin"){let B=q$(h0()),q=Y$(),X=`<?xml version="1.0" encoding="UTF-8"?>
|
|
51
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
52
|
+
<plist version="1.0">
|
|
53
|
+
<dict>
|
|
54
|
+
<key>Label</key>
|
|
55
|
+
<string>com.agentsoc.syslog-beacon</string>
|
|
56
|
+
<key>UserName</key>
|
|
57
|
+
<string>${B}</string>
|
|
58
|
+
<key>ProgramArguments</key>
|
|
59
|
+
<array>
|
|
60
|
+
<string>${q}</string>
|
|
61
|
+
<string>${Q}</string>
|
|
62
|
+
<string>run</string>
|
|
63
|
+
</array>
|
|
64
|
+
<key>RunAtLoad</key>
|
|
65
|
+
<true/>
|
|
66
|
+
<key>KeepAlive</key>
|
|
67
|
+
<true/>
|
|
68
|
+
</dict>
|
|
69
|
+
</plist>
|
|
70
|
+
`,G="/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist";await x0("/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist"),Z$("/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist","com.agentsoc.syslog-beacon"),await v0("/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist",X),E("chown",["root:wheel","/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist"],{stdio:"inherit"}),await J0.chmod("/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist",420),B$("/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist"),console.log("[syslog-beacon] Installed launchd service")}else if(process.platform==="win32")console.log("[syslog-beacon] Windows service installation must be done via NSSM or WinSW. Skipping automatic install.");else throw Error(`Platform ${process.platform} is not supported for automatic service installation.`)}import O from"node:fs";import{execFileSync as c0}from"node:child_process";function l0($,z=200){let J=$.replace(/\s+/g," ").trim();return J.length<=z?J:`${J.slice(0,z)}…`}function m0(){if(process.platform==="linux"){if(!O.existsSync("/etc/systemd/system/syslog-beacon.service"))return{manager:"systemd",installed:!1,active:null,stateLabel:"not installed",detail:"No unit at /etc/systemd/system/syslog-beacon.service"};try{let J=c0("systemctl",["is-active","syslog-beacon"],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}).trim();return{manager:"systemd",installed:!0,active:J==="active",stateLabel:J||"unknown"}}catch(J){let Q=J.status,Y=J.stderr?.toString?.()??"";if(Q===3)return{manager:"systemd",installed:!0,active:!1,stateLabel:"inactive"};return{manager:"systemd",installed:!0,active:!1,stateLabel:"unknown",detail:l0(Y||String(J))}}}if(process.platform==="darwin"){if(!O.existsSync("/Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist"))return{manager:"launchd",installed:!1,active:null,stateLabel:"not installed",detail:"No plist at /Library/LaunchDaemons/com.agentsoc.syslog-beacon.plist"};try{let Y=c0("launchctl",["print","system/com.agentsoc.syslog-beacon"],{encoding:"utf8",stdio:["ignore","pipe","pipe"]}).match(/^\s*state\s*=\s*(\S+)/m)?.[1]??"unknown";return{manager:"launchd",installed:!0,active:Y==="running",stateLabel:Y}}catch(J){let Q=J.stderr?.toString?.()??"";return{manager:"launchd",installed:!0,active:null,stateLabel:"unknown",detail:l0(Q||String(J))}}}return{manager:"none",installed:!1,active:null,stateLabel:"unsupported",detail:"Automatic service detection is only available on Linux (systemd) and macOS (launchd)."}}var d0=k0(),I=new S0;I.name("beacon").description("AgentSOC Syslog Beacon - Lightweight background log forwarder").version(d0,"-v, --version");I.command("config").description("Configure the AgentSOC connection").option("-e, --env <env>","Environment: production (default) or development").option("-k, --key <key>","AgentSOC API Key").action(async($)=>{if(!$.key)console.log(`
|
|
71
|
+
[beacon] Missing required option.
|
|
72
|
+
`),console.log(`Usage: beacon config --key <key> [--env production|development]
|
|
73
|
+
`),console.log("Examples:"),console.log(" beacon config --key sk_1234567890abcdef"),console.log(` beacon config --key sk_1234567890abcdef --env development
|
|
74
|
+
`),console.log("Options:"),console.log(" -k, --key <key> AgentSOC API Key (required)"),console.log(` -e, --env <env> production (default) or development; sets ingest + platform API defaults
|
|
75
|
+
`),process.exit(1);let z=await _(),J;try{J=$.env!==void 0?w($.env):i(z.environment)??"production"}catch(Q){console.error("[beacon]",Q instanceof Error?Q.message:String(Q)),process.exit(1)}await y({apiKey:$.key,environment:J,agentId:z.agentId}),console.log("[beacon] Config saved."),console.log(`[beacon] Environment: ${J}`)});I.command("install").description("Install the background service daemon").action(async()=>{try{await g0()}catch($){let z=$ instanceof Error?$.message:String($);console.error(`[beacon] Install failed:
|
|
76
|
+
|
|
77
|
+
${z}
|
|
78
|
+
`),process.exit(1)}});I.command("status").description("Show service state and forwarding statistics").option("--json","Print machine-readable JSON on stdout").action(async($)=>{let z=m0(),J=await b(),Q=C(),Y=await _(),Z=s(Y),B=D0(Y),q=Z?await P0(B,Z):{ok:!1,message:D};if($.json){console.log(JSON.stringify({service:z,stats:J,statsPath:Q,validateKeyUrl:B,context:q.ok?{organizationName:q.organizationName,organizationSlug:q.organizationSlug,apiKeyName:q.apiKeyName}:{error:q.message}},null,2));return}let X=26,G=(W,K)=>{console.log(` ${W.padEnd(X)}${K}`)};if(console.log(`
|
|
79
|
+
AgentSOC Beacon — Status
|
|
80
|
+
`),console.log(" Account"),q.ok)G("Organization",q.organizationName??"(name unavailable — check platform API / database)"),G("API key",q.apiKeyName);else G("Connection",q.message);if(console.log(`
|
|
81
|
+
Service`),G(`Daemon (${z.manager})`,z.installed?z.stateLabel:"not installed"),z.active===!0)G("Running","yes");else if(z.active===!1)G("Running","no");else G("Running","n/a");if(z.detail)G("Note",z.detail);if(console.log(`
|
|
82
|
+
Forwarding (this machine)`),G("Log entries forwarded",String(J.logsForwarded)),G("Successful batches",String(J.batchesSucceeded)),G("Failed batches",String(J.batchesFailed)),J.updatedAt&&J.updatedAt!==new Date(0).toISOString())G("Last stats update",J.updatedAt);else G("Last stats update","(none yet)");if(J.lastError)G("Last error",J.lastError);console.log()});I.command("update").description("Check for a newer Beacon CLI and optionally install it").option("--json","Print machine-readable JSON on stdout").option("-y, --yes","Run npm install -g @agentsoc/beacon@latest (non-interactive upgrade)").action(async($)=>{let z=d0,J=await E0();if($.json){let q=J.ok?J.info.latestVersion:null,X=q!=null&&q.length>0&&n(z,q);if(console.log(JSON.stringify({currentVersion:z,registry:"https://registry.npmjs.org/@agentsoc%2fbeacon",remote:J.ok?J.info:null,error:J.ok?void 0:J.message,updateAvailable:J.ok?X:null},null,2)),!J.ok)process.exit(1);return}if(!J.ok)console.error(`[beacon] Could not reach npm registry: ${J.message}`),console.error("[beacon] You can still run: npm install -g @agentsoc/beacon@latest"),process.exit(1);let{info:Q}=J,Y=Q.latestVersion;if(console.log(`
|
|
83
|
+
AgentSOC Beacon — Update check
|
|
84
|
+
`),console.log(` This install ${z}`),Y)console.log(` Latest on registry ${Y}`);else console.log(" Latest on registry (unavailable — unexpected npm response)");let Z=Boolean(Y&&Y.length>0),B=Z&&n(z,Y);if(Z&&!B){console.log(`
|
|
85
|
+
You are on the latest published version.
|
|
86
|
+
`);return}if(Z&&B)console.log(`
|
|
87
|
+
A newer version is available.
|
|
88
|
+
`);else console.log(`
|
|
89
|
+
Compare versions manually, or reinstall with:
|
|
90
|
+
`);if(console.log(` ${Q.install.npm}`),console.log(` ${Q.install.bun}`),console.log(` ${Q.install.pnpm}`),Q.docsUrl)console.log(`
|
|
91
|
+
Docs: ${Q.docsUrl}`);if($.yes){if(!B&&Z){console.log(`
|
|
92
|
+
[beacon] Already up to date — skipping install.
|
|
93
|
+
`);return}console.log(`
|
|
94
|
+
[beacon] Running npm install -g @agentsoc/beacon@latest …
|
|
95
|
+
`);let q=process.platform==="win32"?"npm.cmd":"npm";try{X$(q,["install","-g","@agentsoc/beacon@latest"],{stdio:"inherit",env:process.env}),console.log("\n[beacon] Update finished. Run `beacon --version` to verify.\n")}catch{process.exit(1)}return}console.log(`
|
|
96
|
+
To upgrade now, run the same command with --yes
|
|
97
|
+
`)});I.command("run").description("Run the forwarder daemon (foreground)").option("--batch-size <n>","Batch size","25").option("--flush-ms <n>","Flush interval in ms","2000").action(async($)=>{let z=await _(),J=s(z),Q=N0(z);if(!J)console.error(`[beacon] ${D}`),process.exit(1);console.log("[beacon] Starting in foreground...");let Y=await O0({apiKey:J,ingestUrl:Q,batchSize:parseInt($.batchSize,10),flushMs:parseInt($.flushMs,10)}),Z=async()=>{console.log(`
|
|
98
|
+
[beacon] Stopping...`),await Y.stop(),process.exit(0)};process.on("SIGINT",Z),process.on("SIGTERM",Z)});I.parse(process.argv);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-install.d.ts","sourceRoot":"","sources":["../src/service-install.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"service-install.d.ts","sourceRoot":"","sources":["../src/service-install.ts"],"names":[],"mappings":"AA4IA,wBAAsB,cAAc,kBA4EnC"}
|
package/dist/service-install.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { constants as fsConstants } from 'node:fs';
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { execFileSync, execSync } from 'node:child_process';
|
|
5
6
|
import { BEACON_CONFIG_REQUIRED_MESSAGE, loadConfig } from './config.js';
|
|
@@ -82,6 +83,35 @@ function launchctlBootoutSystem(plistPath, label) {
|
|
|
82
83
|
// not loaded yet
|
|
83
84
|
}
|
|
84
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Config and stats paths use os.homedir(). A LaunchDaemon/systemd unit runs as root by
|
|
88
|
+
* default, which points at /var/root (macOS) or /root — not the user who ran `beacon config`.
|
|
89
|
+
* Prefer SUDO_USER from `sudo`; otherwise the current login user when not root.
|
|
90
|
+
*/
|
|
91
|
+
function resolveDaemonRunAsUsername() {
|
|
92
|
+
const sudoUser = process.env.SUDO_USER?.trim();
|
|
93
|
+
if (sudoUser) {
|
|
94
|
+
return sudoUser;
|
|
95
|
+
}
|
|
96
|
+
const uid = typeof process.getuid === 'function' ? process.getuid() : -1;
|
|
97
|
+
if (uid !== 0) {
|
|
98
|
+
try {
|
|
99
|
+
return os.userInfo().username;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// fall through
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
throw new Error('Cannot determine which user account should run the beacon daemon. ' +
|
|
106
|
+
'Config is stored under that user\'s home directory. ' +
|
|
107
|
+
'Run install from your normal account with sudo, e.g. `sudo beacon install`, not from a root-only shell.');
|
|
108
|
+
}
|
|
109
|
+
function escapePlistString(s) {
|
|
110
|
+
return s
|
|
111
|
+
.replace(/&/g, '&')
|
|
112
|
+
.replace(/</g, '<')
|
|
113
|
+
.replace(/>/g, '>');
|
|
114
|
+
}
|
|
85
115
|
function launchctlBootstrapSystem(plistPath) {
|
|
86
116
|
try {
|
|
87
117
|
execFileSync('launchctl', ['bootstrap', 'system', plistPath], {
|
|
@@ -107,12 +137,14 @@ export async function installService() {
|
|
|
107
137
|
const cliPath = path.resolve(process.argv[1]);
|
|
108
138
|
const command = `${runner} ${cliPath} run`;
|
|
109
139
|
if (process.platform === 'linux') {
|
|
140
|
+
const runAs = resolveDaemonRunAsUsername();
|
|
110
141
|
const serviceUnit = `[Unit]
|
|
111
142
|
Description=AgentSOC Syslog Beacon
|
|
112
143
|
After=network.target
|
|
113
144
|
|
|
114
145
|
[Service]
|
|
115
146
|
Type=simple
|
|
147
|
+
User=${runAs}
|
|
116
148
|
ExecStart=${command}
|
|
117
149
|
Restart=always
|
|
118
150
|
RestartSec=10
|
|
@@ -131,6 +163,7 @@ WantedBy=multi-user.target
|
|
|
131
163
|
}
|
|
132
164
|
else if (process.platform === 'darwin') {
|
|
133
165
|
const label = 'com.agentsoc.syslog-beacon';
|
|
166
|
+
const runAs = escapePlistString(resolveDaemonRunAsUsername());
|
|
134
167
|
const launchdRunner = resolveLaunchdRunner();
|
|
135
168
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
136
169
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -138,6 +171,8 @@ WantedBy=multi-user.target
|
|
|
138
171
|
<dict>
|
|
139
172
|
<key>Label</key>
|
|
140
173
|
<string>${label}</string>
|
|
174
|
+
<key>UserName</key>
|
|
175
|
+
<string>${runAs}</string>
|
|
141
176
|
<key>ProgramArguments</key>
|
|
142
177
|
<array>
|
|
143
178
|
<string>${launchdRunner}</string>
|