@alan-ai-hq/agent-manager 0.1.90 → 0.1.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +806 -796
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -15451,7 +15451,7 @@ function describeError(error61) {
|
|
|
15451
15451
|
}
|
|
15452
15452
|
|
|
15453
15453
|
// src/version.ts
|
|
15454
|
-
var AGENT_VERSION = "0.1.
|
|
15454
|
+
var AGENT_VERSION = "0.1.91";
|
|
15455
15455
|
|
|
15456
15456
|
// src/daemon-worktree.ts
|
|
15457
15457
|
var import_node_child_process3 = require("child_process");
|
|
@@ -42795,6 +42795,7 @@ function buildCodexEffortArgs(selectedEffortLevel, options) {
|
|
|
42795
42795
|
return ["-c", `model_reasoning_effort=${level}`];
|
|
42796
42796
|
}
|
|
42797
42797
|
var CODEX_STARTUP_TIMEOUT_MS = 3e5;
|
|
42798
|
+
var ALAN_MCP_STARTUP_TIMEOUT_SEC = 30;
|
|
42798
42799
|
function buildCodexManagedMcpArgs(registration) {
|
|
42799
42800
|
const serverName = managedMcpServerName(registration);
|
|
42800
42801
|
return [
|
|
@@ -42802,7 +42803,11 @@ function buildCodexManagedMcpArgs(registration) {
|
|
|
42802
42803
|
"-c",
|
|
42803
42804
|
`mcp_servers.${serverName}.url=${JSON.stringify(registration.url)}`,
|
|
42804
42805
|
"-c",
|
|
42805
|
-
`mcp_servers.${serverName}.env_http_headers.x-alan-run-reference=${JSON.stringify(ALAN_RUN_REFERENCE_ENV)}
|
|
42806
|
+
`mcp_servers.${serverName}.env_http_headers.x-alan-run-reference=${JSON.stringify(ALAN_RUN_REFERENCE_ENV)}`,
|
|
42807
|
+
"-c",
|
|
42808
|
+
`mcp_servers.${serverName}.required=true`,
|
|
42809
|
+
"-c",
|
|
42810
|
+
`mcp_servers.${serverName}.startup_timeout_sec=${ALAN_MCP_STARTUP_TIMEOUT_SEC}`
|
|
42806
42811
|
];
|
|
42807
42812
|
}
|
|
42808
42813
|
function createCodexRuntimeBackend(command = "codex", defaultArgs = []) {
|
|
@@ -82145,164 +82150,785 @@ function runMcpIntegrationCommand(args, options = {}) {
|
|
|
82145
82150
|
throw new Error(`Unknown integrations action: ${action}`);
|
|
82146
82151
|
}
|
|
82147
82152
|
|
|
82148
|
-
// src/
|
|
82149
|
-
var
|
|
82150
|
-
|
|
82151
|
-
|
|
82152
|
-
|
|
82153
|
-
|
|
82154
|
-
|
|
82155
|
-
|
|
82156
|
-
|
|
82157
|
-
|
|
82158
|
-
return new _AgentLifecycleLogger({ ...this.context, ...context });
|
|
82159
|
-
}
|
|
82160
|
-
debug(event, fields = {}) {
|
|
82161
|
-
this.log("debug", event, fields);
|
|
82162
|
-
}
|
|
82163
|
-
info(event, fields = {}) {
|
|
82164
|
-
this.log("info", event, fields);
|
|
82165
|
-
}
|
|
82166
|
-
warn(event, fields = {}) {
|
|
82167
|
-
this.log("warn", event, fields);
|
|
82168
|
-
}
|
|
82169
|
-
error(event, fields = {}) {
|
|
82170
|
-
this.log("error", event, fields);
|
|
82171
|
-
}
|
|
82172
|
-
log(level, event, fields) {
|
|
82173
|
-
const record2 = omitUndefined({
|
|
82174
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
82175
|
-
level,
|
|
82176
|
-
component: "agent-manager",
|
|
82177
|
-
event,
|
|
82178
|
-
...this.context,
|
|
82179
|
-
...normalizeFields(fields)
|
|
82180
|
-
});
|
|
82181
|
-
console[level](JSON.stringify(record2));
|
|
82182
|
-
}
|
|
82183
|
-
};
|
|
82184
|
-
function lifecycleContextFromEnv(env) {
|
|
82185
|
-
return normalizeContext({
|
|
82186
|
-
taskId: env.ALAN_TASK_ID,
|
|
82187
|
-
conversationId: env.ALAN_SESSION_ID,
|
|
82188
|
-
runId: env.ALAN_RUN_ID,
|
|
82189
|
-
sandboxId: env.ALAN_SANDBOX_ID,
|
|
82190
|
-
provider: env.ALAN_SANDBOX_PROVIDER,
|
|
82191
|
-
backendKind: env.ALAN_BACKEND_KIND,
|
|
82192
|
-
agentVersion: AGENT_VERSION
|
|
82193
|
-
});
|
|
82194
|
-
}
|
|
82195
|
-
function normalizeContext(context) {
|
|
82196
|
-
return omitUndefined({
|
|
82197
|
-
...context,
|
|
82198
|
-
agentVersion: context.agentVersion ?? AGENT_VERSION
|
|
82199
|
-
});
|
|
82153
|
+
// src/service-manager.ts
|
|
82154
|
+
var import_node_child_process9 = require("child_process");
|
|
82155
|
+
var import_node_fs25 = require("fs");
|
|
82156
|
+
var import_node_os16 = require("os");
|
|
82157
|
+
var import_node_path27 = require("path");
|
|
82158
|
+
var SERVICE_LABEL = "ai.tryalan.agent";
|
|
82159
|
+
var SYSTEMD_UNIT = "alan-agent.service";
|
|
82160
|
+
var WINDOWS_TASK = "Alan Agent";
|
|
82161
|
+
function xml(value2) {
|
|
82162
|
+
return value2.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
82200
82163
|
}
|
|
82201
|
-
function
|
|
82202
|
-
|
|
82203
|
-
for (const [key, value2] of Object.entries(fields)) {
|
|
82204
|
-
if (value2 instanceof Error) {
|
|
82205
|
-
normalized[key] = {
|
|
82206
|
-
name: value2.name,
|
|
82207
|
-
message: value2.message,
|
|
82208
|
-
stack: value2.stack
|
|
82209
|
-
};
|
|
82210
|
-
} else {
|
|
82211
|
-
normalized[key] = value2;
|
|
82212
|
-
}
|
|
82213
|
-
}
|
|
82214
|
-
return normalized;
|
|
82164
|
+
function systemdArg(value2) {
|
|
82165
|
+
return `"${value2.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
82215
82166
|
}
|
|
82216
|
-
function
|
|
82217
|
-
return
|
|
82167
|
+
function powershellLiteral(value2) {
|
|
82168
|
+
return `'${value2.replaceAll("'", "''")}'`;
|
|
82218
82169
|
}
|
|
82219
|
-
|
|
82220
|
-
|
|
82221
|
-
|
|
82222
|
-
var __defProp3 = Object.defineProperty;
|
|
82223
|
-
var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
|
|
82224
|
-
var __getOwnPropNames3 = Object.getOwnPropertyNames;
|
|
82225
|
-
var __getProtoOf3 = Object.getPrototypeOf;
|
|
82226
|
-
var __hasOwnProp3 = Object.prototype.hasOwnProperty;
|
|
82227
|
-
var __commonJSMin2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
82228
|
-
var __exportAll2 = (all, symbols) => {
|
|
82229
|
-
let target = {};
|
|
82230
|
-
for (var name in all) {
|
|
82231
|
-
__defProp3(target, name, {
|
|
82232
|
-
get: all[name],
|
|
82233
|
-
enumerable: true
|
|
82234
|
-
});
|
|
82170
|
+
function serviceNames(profile) {
|
|
82171
|
+
if (profile === "production") {
|
|
82172
|
+
return { launchd: SERVICE_LABEL, systemd: SYSTEMD_UNIT, windows: WINDOWS_TASK };
|
|
82235
82173
|
}
|
|
82236
|
-
|
|
82237
|
-
|
|
82174
|
+
const suffix = profile === "custom" ? "prod" : profile;
|
|
82175
|
+
const title = `${suffix[0]?.toUpperCase()}${suffix.slice(1)}`;
|
|
82176
|
+
return {
|
|
82177
|
+
launchd: `${SERVICE_LABEL}.${suffix}`,
|
|
82178
|
+
systemd: `alan-agent-${suffix}.service`,
|
|
82179
|
+
windows: `${WINDOWS_TASK} ${title}`
|
|
82180
|
+
};
|
|
82181
|
+
}
|
|
82182
|
+
function buildDaemonServicePlan(input2) {
|
|
82183
|
+
const daemonArgs = [input2.nodeExecutable, input2.cliEntry, "daemon", "--profile", input2.profile];
|
|
82184
|
+
const names = serviceNames(input2.profile);
|
|
82185
|
+
if (input2.platform === "darwin") {
|
|
82186
|
+
const userId = input2.userId ?? process.getuid?.();
|
|
82187
|
+
if (userId === void 0) throw new Error("Cannot determine the current macOS user ID");
|
|
82188
|
+
const domain2 = `gui/${userId}`;
|
|
82189
|
+
const serviceTarget = `${domain2}/${names.launchd}`;
|
|
82190
|
+
const manifestPath = (0, import_node_path27.join)(input2.homeDir, "Library", "LaunchAgents", `${names.launchd}.plist`);
|
|
82191
|
+
const logDir = (0, import_node_path27.join)(resolveAgentConfigDirectory(input2.profile, input2.homeDir), "logs");
|
|
82192
|
+
const programArguments = daemonArgs.map((arg) => ` <string>${xml(arg)}</string>`).join("\n");
|
|
82193
|
+
const environmentEntries = Object.entries(input2.environment ?? {}).map(([key, value2]) => ` <key>${xml(key)}</key>
|
|
82194
|
+
<string>${xml(value2)}</string>`).join("\n");
|
|
82195
|
+
const environmentBlock = environmentEntries ? ` <key>EnvironmentVariables</key>
|
|
82196
|
+
<dict>
|
|
82197
|
+
${environmentEntries}
|
|
82198
|
+
</dict>
|
|
82199
|
+
` : "";
|
|
82200
|
+
const manifest = `<?xml version="1.0" encoding="UTF-8"?>
|
|
82201
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
82202
|
+
<plist version="1.0">
|
|
82203
|
+
<dict>
|
|
82204
|
+
<key>Label</key>
|
|
82205
|
+
<string>${names.launchd}</string>
|
|
82206
|
+
<key>ProgramArguments</key>
|
|
82207
|
+
<array>
|
|
82208
|
+
${programArguments}
|
|
82209
|
+
</array>
|
|
82210
|
+
${environmentBlock} <key>RunAtLoad</key>
|
|
82211
|
+
<true/>
|
|
82212
|
+
<key>KeepAlive</key>
|
|
82213
|
+
<dict>
|
|
82214
|
+
<key>SuccessfulExit</key>
|
|
82215
|
+
<false/>
|
|
82216
|
+
</dict>
|
|
82217
|
+
<key>ThrottleInterval</key>
|
|
82218
|
+
<integer>5</integer>
|
|
82219
|
+
<key>StandardOutPath</key>
|
|
82220
|
+
<string>${xml((0, import_node_path27.join)(logDir, "daemon.log"))}</string>
|
|
82221
|
+
<key>StandardErrorPath</key>
|
|
82222
|
+
<string>${xml((0, import_node_path27.join)(logDir, "daemon-error.log"))}</string>
|
|
82223
|
+
</dict>
|
|
82224
|
+
</plist>
|
|
82225
|
+
`;
|
|
82226
|
+
return {
|
|
82227
|
+
platform: "darwin",
|
|
82228
|
+
manifestPath,
|
|
82229
|
+
manifest,
|
|
82230
|
+
logDirectory: logDir,
|
|
82231
|
+
loadDefinitionCommands: [
|
|
82232
|
+
{
|
|
82233
|
+
command: "launchctl",
|
|
82234
|
+
args: ["bootstrap", domain2, manifestPath],
|
|
82235
|
+
tolerateFailure: true
|
|
82236
|
+
}
|
|
82237
|
+
],
|
|
82238
|
+
reloadDefinitionCommands: [
|
|
82239
|
+
{
|
|
82240
|
+
command: "launchctl",
|
|
82241
|
+
args: ["bootout", domain2, manifestPath],
|
|
82242
|
+
tolerateFailure: true
|
|
82243
|
+
},
|
|
82244
|
+
{
|
|
82245
|
+
command: "launchctl",
|
|
82246
|
+
args: ["bootstrap", domain2, manifestPath],
|
|
82247
|
+
tolerateFailure: false
|
|
82248
|
+
}
|
|
82249
|
+
],
|
|
82250
|
+
enableCommands: [
|
|
82251
|
+
{
|
|
82252
|
+
command: "launchctl",
|
|
82253
|
+
args: ["enable", serviceTarget],
|
|
82254
|
+
tolerateFailure: true
|
|
82255
|
+
}
|
|
82256
|
+
],
|
|
82257
|
+
startCommands: [
|
|
82258
|
+
{
|
|
82259
|
+
command: "launchctl",
|
|
82260
|
+
args: ["kickstart", serviceTarget],
|
|
82261
|
+
tolerateFailure: false
|
|
82262
|
+
}
|
|
82263
|
+
],
|
|
82264
|
+
stopCommands: [
|
|
82265
|
+
{
|
|
82266
|
+
command: "launchctl",
|
|
82267
|
+
args: ["kill", "SIGTERM", serviceTarget],
|
|
82268
|
+
tolerateFailure: true
|
|
82269
|
+
}
|
|
82270
|
+
],
|
|
82271
|
+
replaceCommands: [
|
|
82272
|
+
{
|
|
82273
|
+
command: "launchctl",
|
|
82274
|
+
args: ["bootout", domain2, manifestPath],
|
|
82275
|
+
tolerateFailure: true
|
|
82276
|
+
},
|
|
82277
|
+
{
|
|
82278
|
+
command: "launchctl",
|
|
82279
|
+
args: ["bootstrap", domain2, manifestPath],
|
|
82280
|
+
tolerateFailure: false
|
|
82281
|
+
},
|
|
82282
|
+
{
|
|
82283
|
+
command: "launchctl",
|
|
82284
|
+
args: ["kickstart", "-k", serviceTarget],
|
|
82285
|
+
tolerateFailure: false
|
|
82286
|
+
}
|
|
82287
|
+
],
|
|
82288
|
+
uninstallCommands: [
|
|
82289
|
+
{
|
|
82290
|
+
command: "launchctl",
|
|
82291
|
+
args: ["bootout", domain2, manifestPath],
|
|
82292
|
+
tolerateFailure: true
|
|
82293
|
+
}
|
|
82294
|
+
],
|
|
82295
|
+
statusCommand: {
|
|
82296
|
+
command: "launchctl",
|
|
82297
|
+
args: ["print", serviceTarget],
|
|
82298
|
+
tolerateFailure: true
|
|
82299
|
+
},
|
|
82300
|
+
isActiveCommand: {
|
|
82301
|
+
command: "launchctl",
|
|
82302
|
+
args: ["print", serviceTarget],
|
|
82303
|
+
tolerateFailure: true
|
|
82304
|
+
},
|
|
82305
|
+
lingerStatusCommand: null
|
|
82306
|
+
};
|
|
82238
82307
|
}
|
|
82239
|
-
|
|
82240
|
-
|
|
82241
|
-
|
|
82242
|
-
|
|
82243
|
-
|
|
82244
|
-
|
|
82245
|
-
|
|
82246
|
-
|
|
82247
|
-
|
|
82248
|
-
|
|
82249
|
-
|
|
82308
|
+
if (input2.platform === "linux") {
|
|
82309
|
+
const manifestPath = (0, import_node_path27.join)(input2.homeDir, ".config", "systemd", "user", names.systemd);
|
|
82310
|
+
const environmentLines = Object.entries(input2.environment ?? {}).map(([key, value2]) => `Environment=${systemdArg(`${key}=${value2}`)}`).join("\n");
|
|
82311
|
+
const manifest = `[Unit]
|
|
82312
|
+
Description=Alan local agent daemon
|
|
82313
|
+
After=network-online.target
|
|
82314
|
+
Wants=network-online.target
|
|
82315
|
+
StartLimitIntervalSec=300
|
|
82316
|
+
StartLimitBurst=3
|
|
82317
|
+
|
|
82318
|
+
[Service]
|
|
82319
|
+
Type=simple
|
|
82320
|
+
${environmentLines ? `${environmentLines}
|
|
82321
|
+
` : ""}ExecStart=${daemonArgs.map(systemdArg).join(" ")}
|
|
82322
|
+
Restart=on-failure
|
|
82323
|
+
RestartSec=5
|
|
82324
|
+
|
|
82325
|
+
[Install]
|
|
82326
|
+
WantedBy=default.target
|
|
82327
|
+
`;
|
|
82328
|
+
return {
|
|
82329
|
+
platform: "linux",
|
|
82330
|
+
manifestPath,
|
|
82331
|
+
manifest,
|
|
82332
|
+
logDirectory: null,
|
|
82333
|
+
loadDefinitionCommands: [
|
|
82334
|
+
{
|
|
82335
|
+
command: "systemctl",
|
|
82336
|
+
args: ["--user", "daemon-reload"],
|
|
82337
|
+
tolerateFailure: false
|
|
82338
|
+
}
|
|
82339
|
+
],
|
|
82340
|
+
reloadDefinitionCommands: [
|
|
82341
|
+
{
|
|
82342
|
+
command: "systemctl",
|
|
82343
|
+
args: ["--user", "daemon-reload"],
|
|
82344
|
+
tolerateFailure: false
|
|
82345
|
+
}
|
|
82346
|
+
],
|
|
82347
|
+
enableCommands: [
|
|
82348
|
+
{
|
|
82349
|
+
command: "systemctl",
|
|
82350
|
+
args: ["--user", "enable", names.systemd],
|
|
82351
|
+
tolerateFailure: false
|
|
82352
|
+
}
|
|
82353
|
+
],
|
|
82354
|
+
startCommands: [
|
|
82355
|
+
{
|
|
82356
|
+
command: "systemctl",
|
|
82357
|
+
args: ["--user", "start", names.systemd],
|
|
82358
|
+
tolerateFailure: false
|
|
82359
|
+
}
|
|
82360
|
+
],
|
|
82361
|
+
stopCommands: [
|
|
82362
|
+
{
|
|
82363
|
+
command: "systemctl",
|
|
82364
|
+
args: ["--user", "stop", names.systemd],
|
|
82365
|
+
tolerateFailure: true
|
|
82366
|
+
}
|
|
82367
|
+
],
|
|
82368
|
+
replaceCommands: [
|
|
82369
|
+
{
|
|
82370
|
+
command: "systemctl",
|
|
82371
|
+
args: ["--user", "daemon-reload"],
|
|
82372
|
+
tolerateFailure: false
|
|
82373
|
+
},
|
|
82374
|
+
{
|
|
82375
|
+
command: "systemctl",
|
|
82376
|
+
args: ["--user", "restart", names.systemd],
|
|
82377
|
+
tolerateFailure: false
|
|
82378
|
+
}
|
|
82379
|
+
],
|
|
82380
|
+
uninstallCommands: [
|
|
82381
|
+
{
|
|
82382
|
+
command: "systemctl",
|
|
82383
|
+
args: ["--user", "disable", "--now", names.systemd],
|
|
82384
|
+
tolerateFailure: true
|
|
82385
|
+
},
|
|
82386
|
+
{
|
|
82387
|
+
command: "systemctl",
|
|
82388
|
+
args: ["--user", "daemon-reload"],
|
|
82389
|
+
tolerateFailure: false
|
|
82390
|
+
}
|
|
82391
|
+
],
|
|
82392
|
+
statusCommand: {
|
|
82393
|
+
command: "systemctl",
|
|
82394
|
+
args: ["--user", "status", names.systemd, "--no-pager"],
|
|
82395
|
+
tolerateFailure: true
|
|
82396
|
+
},
|
|
82397
|
+
isActiveCommand: {
|
|
82398
|
+
command: "systemctl",
|
|
82399
|
+
args: ["--user", "is-active", names.systemd],
|
|
82400
|
+
tolerateFailure: true
|
|
82401
|
+
},
|
|
82402
|
+
lingerStatusCommand: {
|
|
82403
|
+
command: "loginctl",
|
|
82404
|
+
args: ["show-user", "$(id -un)", "-p", "Linger"],
|
|
82405
|
+
tolerateFailure: true
|
|
82250
82406
|
}
|
|
82251
|
-
}
|
|
82407
|
+
};
|
|
82252
82408
|
}
|
|
82253
|
-
|
|
82254
|
-
};
|
|
82255
|
-
|
|
82256
|
-
|
|
82257
|
-
|
|
82258
|
-
|
|
82259
|
-
|
|
82260
|
-
|
|
82261
|
-
|
|
82262
|
-
|
|
82263
|
-
|
|
82264
|
-
|
|
82265
|
-
|
|
82266
|
-
|
|
82267
|
-
|
|
82268
|
-
|
|
82269
|
-
|
|
82270
|
-
|
|
82271
|
-
|
|
82272
|
-
|
|
82273
|
-
|
|
82274
|
-
|
|
82409
|
+
const environmentPrefix = Object.entries(input2.environment ?? {}).map(([key, value2]) => `$env:${key} = ${powershellLiteral(value2)}`).join("; ");
|
|
82410
|
+
const directArgument = [input2.cliEntry, "daemon", "--profile", input2.profile].map((part) => part.includes(" ") ? `"${part}"` : part).join(" ");
|
|
82411
|
+
const executable = powershellLiteral(environmentPrefix ? "powershell.exe" : input2.nodeExecutable);
|
|
82412
|
+
const argument = powershellLiteral(
|
|
82413
|
+
environmentPrefix ? `-NoProfile -NonInteractive -WindowStyle Hidden -Command "${environmentPrefix}; & ${powershellLiteral(input2.nodeExecutable)} ${powershellLiteral(input2.cliEntry)} daemon --profile ${input2.profile}"` : directArgument
|
|
82414
|
+
);
|
|
82415
|
+
const registerScript = [
|
|
82416
|
+
"$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name",
|
|
82417
|
+
`$action = New-ScheduledTaskAction -Execute ${executable} -Argument ${argument}`,
|
|
82418
|
+
"$trigger = New-ScheduledTaskTrigger -AtLogOn -User $currentUser",
|
|
82419
|
+
"$principal = New-ScheduledTaskPrincipal -UserId $currentUser -LogonType Interactive -RunLevel Limited",
|
|
82420
|
+
"$settings = New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -ExecutionTimeLimit ([TimeSpan]::Zero)",
|
|
82421
|
+
`Register-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Force | Out-Null`
|
|
82422
|
+
].join("; ");
|
|
82423
|
+
return {
|
|
82424
|
+
platform: "win32",
|
|
82425
|
+
manifestPath: null,
|
|
82426
|
+
manifest: null,
|
|
82427
|
+
logDirectory: null,
|
|
82428
|
+
loadDefinitionCommands: [
|
|
82429
|
+
{
|
|
82430
|
+
command: "powershell.exe",
|
|
82431
|
+
args: ["-NoProfile", "-NonInteractive", "-Command", registerScript],
|
|
82432
|
+
tolerateFailure: false
|
|
82433
|
+
}
|
|
82434
|
+
],
|
|
82435
|
+
reloadDefinitionCommands: [
|
|
82436
|
+
{
|
|
82437
|
+
command: "powershell.exe",
|
|
82438
|
+
args: ["-NoProfile", "-NonInteractive", "-Command", registerScript],
|
|
82439
|
+
tolerateFailure: false
|
|
82440
|
+
}
|
|
82441
|
+
],
|
|
82442
|
+
enableCommands: [],
|
|
82443
|
+
startCommands: [
|
|
82444
|
+
{
|
|
82445
|
+
command: "powershell.exe",
|
|
82446
|
+
args: [
|
|
82447
|
+
"-NoProfile",
|
|
82448
|
+
"-NonInteractive",
|
|
82449
|
+
"-Command",
|
|
82450
|
+
`Start-ScheduledTask -TaskName ${powershellLiteral(names.windows)}`
|
|
82451
|
+
],
|
|
82452
|
+
tolerateFailure: false
|
|
82453
|
+
}
|
|
82454
|
+
],
|
|
82455
|
+
stopCommands: [
|
|
82456
|
+
{
|
|
82457
|
+
command: "powershell.exe",
|
|
82458
|
+
args: [
|
|
82459
|
+
"-NoProfile",
|
|
82460
|
+
"-NonInteractive",
|
|
82461
|
+
"-Command",
|
|
82462
|
+
`Stop-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -ErrorAction SilentlyContinue`
|
|
82463
|
+
],
|
|
82464
|
+
tolerateFailure: true
|
|
82465
|
+
}
|
|
82466
|
+
],
|
|
82467
|
+
replaceCommands: [
|
|
82468
|
+
{
|
|
82469
|
+
command: "powershell.exe",
|
|
82470
|
+
args: [
|
|
82471
|
+
"-NoProfile",
|
|
82472
|
+
"-NonInteractive",
|
|
82473
|
+
"-Command",
|
|
82474
|
+
`${registerScript}; Start-ScheduledTask -TaskName ${powershellLiteral(names.windows)}`
|
|
82475
|
+
],
|
|
82476
|
+
tolerateFailure: false
|
|
82477
|
+
}
|
|
82478
|
+
],
|
|
82479
|
+
uninstallCommands: [
|
|
82480
|
+
{
|
|
82481
|
+
command: "powershell.exe",
|
|
82482
|
+
args: [
|
|
82483
|
+
"-NoProfile",
|
|
82484
|
+
"-NonInteractive",
|
|
82485
|
+
"-Command",
|
|
82486
|
+
`Unregister-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -Confirm:$false -ErrorAction SilentlyContinue`
|
|
82487
|
+
],
|
|
82488
|
+
tolerateFailure: true
|
|
82489
|
+
}
|
|
82490
|
+
],
|
|
82491
|
+
statusCommand: {
|
|
82492
|
+
command: "powershell.exe",
|
|
82493
|
+
args: [
|
|
82494
|
+
"-NoProfile",
|
|
82495
|
+
"-NonInteractive",
|
|
82496
|
+
"-Command",
|
|
82497
|
+
`Get-ScheduledTask -TaskName ${powershellLiteral(names.windows)} | Format-List TaskName,State`
|
|
82498
|
+
],
|
|
82499
|
+
tolerateFailure: true
|
|
82500
|
+
},
|
|
82501
|
+
isActiveCommand: {
|
|
82502
|
+
command: "powershell.exe",
|
|
82503
|
+
args: [
|
|
82504
|
+
"-NoProfile",
|
|
82505
|
+
"-NonInteractive",
|
|
82506
|
+
"-Command",
|
|
82507
|
+
`(Get-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -ErrorAction SilentlyContinue).State`
|
|
82508
|
+
],
|
|
82509
|
+
tolerateFailure: true
|
|
82510
|
+
},
|
|
82511
|
+
lingerStatusCommand: null
|
|
82512
|
+
};
|
|
82275
82513
|
}
|
|
82276
|
-
|
|
82277
|
-
|
|
82278
|
-
|
|
82279
|
-
|
|
82280
|
-
const brands = /* @__PURE__ */ new Set();
|
|
82281
|
-
let current = ctor;
|
|
82282
|
-
while (typeof current === "function") {
|
|
82283
|
-
const brand = current.mcpBrand;
|
|
82284
|
-
if (Object.prototype.hasOwnProperty.call(current, "mcpBrand") && typeof brand === "string") brands.add(brand);
|
|
82285
|
-
current = Object.getPrototypeOf(current);
|
|
82514
|
+
function resolveCurrentPlatform() {
|
|
82515
|
+
const currentPlatform = (0, import_node_os16.platform)();
|
|
82516
|
+
if (currentPlatform !== "darwin" && currentPlatform !== "linux" && currentPlatform !== "win32") {
|
|
82517
|
+
throw new Error(`Daemon service installation is not supported on ${currentPlatform}`);
|
|
82286
82518
|
}
|
|
82287
|
-
|
|
82288
|
-
|
|
82289
|
-
|
|
82290
|
-
|
|
82291
|
-
|
|
82519
|
+
return currentPlatform;
|
|
82520
|
+
}
|
|
82521
|
+
function currentServicePlan(args, runtime) {
|
|
82522
|
+
const currentPlatform = resolveCurrentPlatform();
|
|
82523
|
+
const profile = resolveEndpointProfileFromArgs(args);
|
|
82524
|
+
const cliEntry = runtime?.cliEntry ?? process.argv[1];
|
|
82525
|
+
if (!cliEntry) throw new Error("Cannot determine the alan-agent executable path");
|
|
82526
|
+
return buildDaemonServicePlan({
|
|
82527
|
+
platform: currentPlatform,
|
|
82528
|
+
homeDir: (0, import_node_os16.homedir)(),
|
|
82529
|
+
nodeExecutable: runtime?.executable ?? process.execPath,
|
|
82530
|
+
cliEntry: (0, import_node_path27.resolve)(cliEntry),
|
|
82531
|
+
profile,
|
|
82532
|
+
environment: runtime?.environment
|
|
82292
82533
|
});
|
|
82293
82534
|
}
|
|
82294
|
-
function
|
|
82535
|
+
function writeManifestAtomic(path2, contents) {
|
|
82536
|
+
(0, import_node_fs25.mkdirSync)((0, import_node_path27.dirname)(path2), { recursive: true, mode: 448 });
|
|
82537
|
+
const pendingPath = `${path2}.pending-${process.pid}`;
|
|
82295
82538
|
try {
|
|
82296
|
-
|
|
82297
|
-
|
|
82298
|
-
|
|
82299
|
-
|
|
82300
|
-
|
|
82539
|
+
(0, import_node_fs25.writeFileSync)(pendingPath, contents, { mode: 384 });
|
|
82540
|
+
(0, import_node_fs25.chmodSync)(pendingPath, 384);
|
|
82541
|
+
(0, import_node_fs25.renameSync)(pendingPath, path2);
|
|
82542
|
+
} finally {
|
|
82543
|
+
(0, import_node_fs25.rmSync)(pendingPath, { force: true });
|
|
82301
82544
|
}
|
|
82302
|
-
return Function.prototype[Symbol.hasInstance].call(cls, value2);
|
|
82303
82545
|
}
|
|
82304
|
-
|
|
82305
|
-
|
|
82546
|
+
function defaultReadManifest(path2) {
|
|
82547
|
+
if (!(0, import_node_fs25.existsSync)(path2)) return null;
|
|
82548
|
+
return (0, import_node_fs25.readFileSync)(path2, "utf8");
|
|
82549
|
+
}
|
|
82550
|
+
function runServiceCommand(command) {
|
|
82551
|
+
const result = (0, import_node_child_process9.spawnSync)(command.command, command.args, { encoding: "utf8", shell: false });
|
|
82552
|
+
const status = result.status ?? 1;
|
|
82553
|
+
const output2 = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
|
|
82554
|
+
if (status !== 0 && !command.tolerateFailure) {
|
|
82555
|
+
throw new Error(
|
|
82556
|
+
`Service command failed (${command.command} ${command.args.join(" ")}): ${output2 || `exit ${status}`}`
|
|
82557
|
+
);
|
|
82558
|
+
}
|
|
82559
|
+
return { status, output: output2 };
|
|
82560
|
+
}
|
|
82561
|
+
function defaultSleep(ms) {
|
|
82562
|
+
return new Promise((resolveSleep) => {
|
|
82563
|
+
setTimeout(resolveSleep, ms);
|
|
82564
|
+
});
|
|
82565
|
+
}
|
|
82566
|
+
function parseServiceHostState(servicePlatform, result) {
|
|
82567
|
+
const output2 = result.output;
|
|
82568
|
+
if (servicePlatform === "linux") {
|
|
82569
|
+
const trimmed = output2.trim().toLowerCase();
|
|
82570
|
+
if (trimmed === "inactive" || trimmed === "failed" || trimmed === "dead" || /\binactive\b/i.test(output2) || /\bfailed\b/i.test(output2)) {
|
|
82571
|
+
return "stopped";
|
|
82572
|
+
}
|
|
82573
|
+
}
|
|
82574
|
+
if (result.status !== 0) return "unknown";
|
|
82575
|
+
if (servicePlatform === "darwin") {
|
|
82576
|
+
if (/\bstate\s*=\s*running\b/i.test(output2)) return "running";
|
|
82577
|
+
if (/\bstate\s*=\s*(not running|waiting|stopped)\b/i.test(output2)) return "stopped";
|
|
82578
|
+
if (/\bpid\s*=\s*[1-9]\d*\b/i.test(output2)) return "running";
|
|
82579
|
+
if (/could not find service/i.test(output2)) return "stopped";
|
|
82580
|
+
return "unknown";
|
|
82581
|
+
}
|
|
82582
|
+
if (servicePlatform === "linux") {
|
|
82583
|
+
const trimmed = output2.trim().toLowerCase();
|
|
82584
|
+
if (trimmed === "active" || /\bactive\s*\(running\)/i.test(output2)) return "running";
|
|
82585
|
+
if (trimmed === "activating" || trimmed === "reloading") return "starting";
|
|
82586
|
+
return "unknown";
|
|
82587
|
+
}
|
|
82588
|
+
const stateMatch = output2.match(/\b(?:State|state)\s*[:=]\s*(\w+)/);
|
|
82589
|
+
const state = (stateMatch?.[1] ?? output2.trim()).toLowerCase();
|
|
82590
|
+
if (state === "running") return "running";
|
|
82591
|
+
if (state === "ready" || state === "disabled" || state === "queued") return "stopped";
|
|
82592
|
+
return "unknown";
|
|
82593
|
+
}
|
|
82594
|
+
function resolveEnsureDefinitionOutcome(input2) {
|
|
82595
|
+
if (!input2.definitionChanged) {
|
|
82596
|
+
return { changed: false, updatePending: false };
|
|
82597
|
+
}
|
|
82598
|
+
if (input2.hostState === "running" || input2.hostState === "starting") {
|
|
82599
|
+
return { changed: true, updatePending: true };
|
|
82600
|
+
}
|
|
82601
|
+
return { changed: true, updatePending: false };
|
|
82602
|
+
}
|
|
82603
|
+
function shouldStartOnInstall(hostState) {
|
|
82604
|
+
return hostState === "stopped";
|
|
82605
|
+
}
|
|
82606
|
+
function resolveUsername(options) {
|
|
82607
|
+
if (options?.username) return options.username;
|
|
82608
|
+
try {
|
|
82609
|
+
return (0, import_node_os16.userInfo)().username;
|
|
82610
|
+
} catch {
|
|
82611
|
+
return process.env.USER || process.env.USERNAME || "unknown";
|
|
82612
|
+
}
|
|
82613
|
+
}
|
|
82614
|
+
function buildLingerStatusCommand(username) {
|
|
82615
|
+
return {
|
|
82616
|
+
command: "loginctl",
|
|
82617
|
+
args: ["show-user", username, "-p", "Linger"],
|
|
82618
|
+
tolerateFailure: true
|
|
82619
|
+
};
|
|
82620
|
+
}
|
|
82621
|
+
function assertSystemdUserLingerEnabled(options = {}) {
|
|
82622
|
+
const username = resolveUsername(options);
|
|
82623
|
+
const run = options.runCommand ?? runServiceCommand;
|
|
82624
|
+
const result = run(buildLingerStatusCommand(username));
|
|
82625
|
+
if (result.status !== 0) {
|
|
82626
|
+
throw new Error(
|
|
82627
|
+
`Cannot verify systemd user linger for ${username} (loginctl failed). For durable headless VM boot run: sudo loginctl enable-linger ${username}`
|
|
82628
|
+
);
|
|
82629
|
+
}
|
|
82630
|
+
if (!/Linger=yes/i.test(result.output)) {
|
|
82631
|
+
throw new Error(
|
|
82632
|
+
`systemd user linger is disabled for ${username}. For durable headless VM boot run: sudo loginctl enable-linger ${username}`
|
|
82633
|
+
);
|
|
82634
|
+
}
|
|
82635
|
+
}
|
|
82636
|
+
function createHostContext(options = {}) {
|
|
82637
|
+
const args = options.args ?? [];
|
|
82638
|
+
const plan = currentServicePlan(args, options.runtime);
|
|
82639
|
+
const run = options.runCommand ?? runServiceCommand;
|
|
82640
|
+
const sleep4 = options.sleep ?? defaultSleep;
|
|
82641
|
+
const nowMs = options.nowMs ?? Date.now;
|
|
82642
|
+
const readManifest = options.readManifest ?? defaultReadManifest;
|
|
82643
|
+
const writeManifest = options.writeManifest ?? writeManifestAtomic;
|
|
82644
|
+
const removeManifest = options.removeManifest ?? ((path2) => (0, import_node_fs25.rmSync)(path2, { force: true }));
|
|
82645
|
+
const ensureLogDir = options.ensureLogDir ?? (() => {
|
|
82646
|
+
if (plan.logDirectory) (0, import_node_fs25.mkdirSync)(plan.logDirectory, { recursive: true, mode: 448 });
|
|
82647
|
+
});
|
|
82648
|
+
return {
|
|
82649
|
+
args,
|
|
82650
|
+
plan,
|
|
82651
|
+
run,
|
|
82652
|
+
sleep: sleep4,
|
|
82653
|
+
nowMs,
|
|
82654
|
+
readManifest,
|
|
82655
|
+
writeManifest,
|
|
82656
|
+
removeManifest,
|
|
82657
|
+
ensureLogDir,
|
|
82658
|
+
profile: resolveEndpointProfileFromArgs(args)
|
|
82659
|
+
};
|
|
82660
|
+
}
|
|
82661
|
+
function inspectDaemonService(options = {}) {
|
|
82662
|
+
const { plan, run, nowMs } = createHostContext(options);
|
|
82663
|
+
const result = run(plan.isActiveCommand);
|
|
82664
|
+
const state = parseServiceHostState(plan.platform, result);
|
|
82665
|
+
return {
|
|
82666
|
+
state,
|
|
82667
|
+
platform: plan.platform,
|
|
82668
|
+
detail: result.output || void 0,
|
|
82669
|
+
observedAtMs: nowMs()
|
|
82670
|
+
};
|
|
82671
|
+
}
|
|
82672
|
+
function ensureDaemonServiceDefinition(options = {}) {
|
|
82673
|
+
const ctx = createHostContext(options);
|
|
82674
|
+
const { plan, run, readManifest, writeManifest, ensureLogDir } = ctx;
|
|
82675
|
+
let definitionChanged = false;
|
|
82676
|
+
if (plan.manifestPath && plan.manifest) {
|
|
82677
|
+
ensureLogDir();
|
|
82678
|
+
const existing = readManifest(plan.manifestPath);
|
|
82679
|
+
definitionChanged = existing !== plan.manifest;
|
|
82680
|
+
if (definitionChanged) {
|
|
82681
|
+
writeManifest(plan.manifestPath, plan.manifest);
|
|
82682
|
+
}
|
|
82683
|
+
} else if (plan.platform === "win32") {
|
|
82684
|
+
definitionChanged = true;
|
|
82685
|
+
}
|
|
82686
|
+
const inspection = inspectDaemonService(options);
|
|
82687
|
+
const outcome = resolveEnsureDefinitionOutcome({
|
|
82688
|
+
definitionChanged,
|
|
82689
|
+
hostState: inspection.state
|
|
82690
|
+
});
|
|
82691
|
+
if (outcome.updatePending) {
|
|
82692
|
+
return outcome;
|
|
82693
|
+
}
|
|
82694
|
+
if (inspection.state === "running" || inspection.state === "starting") {
|
|
82695
|
+
return outcome;
|
|
82696
|
+
}
|
|
82697
|
+
const definitionCommands = inspection.state === "stopped" ? plan.reloadDefinitionCommands : plan.loadDefinitionCommands;
|
|
82698
|
+
for (const command of definitionCommands) run(command);
|
|
82699
|
+
return outcome;
|
|
82700
|
+
}
|
|
82701
|
+
function enableDaemonService(options = {}) {
|
|
82702
|
+
const { plan, run } = createHostContext(options);
|
|
82703
|
+
for (const command of plan.enableCommands) run(command);
|
|
82704
|
+
}
|
|
82705
|
+
function startDaemonService(options = {}) {
|
|
82706
|
+
const { plan, run } = createHostContext(options);
|
|
82707
|
+
for (const command of plan.startCommands) run(command);
|
|
82708
|
+
}
|
|
82709
|
+
function uninstallDaemonService(args = [], options = {}) {
|
|
82710
|
+
const ctx = createHostContext({ ...options, args: options.args ?? args });
|
|
82711
|
+
for (const command of ctx.plan.uninstallCommands) ctx.run(command);
|
|
82712
|
+
if (ctx.plan.manifestPath) ctx.removeManifest(ctx.plan.manifestPath);
|
|
82713
|
+
console.info("[alan-agent] Per-user daemon service removed");
|
|
82714
|
+
}
|
|
82715
|
+
function installDaemonService(args = [], runtime, options = {}) {
|
|
82716
|
+
const profile = resolveEndpointProfileFromArgs(args);
|
|
82717
|
+
const configPath = resolveAgentConfigPath({ profile });
|
|
82718
|
+
if (!configExistsAtPath(configPath)) {
|
|
82719
|
+
throw new Error(`No ${profile} runtime is configured. Run alan-agent setup or login first.`);
|
|
82720
|
+
}
|
|
82721
|
+
const headless = options.headless ?? args.includes("--headless");
|
|
82722
|
+
const merged = { ...options, args, runtime, headless };
|
|
82723
|
+
const ctx = createHostContext(merged);
|
|
82724
|
+
if (headless) {
|
|
82725
|
+
if (ctx.plan.platform !== "linux") {
|
|
82726
|
+
throw new Error("--headless is only supported on Linux systemd user services");
|
|
82727
|
+
}
|
|
82728
|
+
assertSystemdUserLingerEnabled(merged);
|
|
82729
|
+
}
|
|
82730
|
+
const ensured = ensureDaemonServiceDefinition(merged);
|
|
82731
|
+
enableDaemonService(merged);
|
|
82732
|
+
const inspection = inspectDaemonService(merged);
|
|
82733
|
+
if (ensured.updatePending) {
|
|
82734
|
+
console.info("[alan-agent] Daemon service definition update pending; leaving running service", {
|
|
82735
|
+
profile,
|
|
82736
|
+
state: inspection.state
|
|
82737
|
+
});
|
|
82738
|
+
return;
|
|
82739
|
+
}
|
|
82740
|
+
if (!shouldStartOnInstall(inspection.state)) {
|
|
82741
|
+
console.info("[alan-agent] Per-user daemon service already present", {
|
|
82742
|
+
profile,
|
|
82743
|
+
state: inspection.state
|
|
82744
|
+
});
|
|
82745
|
+
return;
|
|
82746
|
+
}
|
|
82747
|
+
startDaemonService(merged);
|
|
82748
|
+
console.info("[alan-agent] Per-user daemon service installed", { profile });
|
|
82749
|
+
}
|
|
82750
|
+
function printDaemonServiceStatus(args = []) {
|
|
82751
|
+
const plan = currentServicePlan(args);
|
|
82752
|
+
const result = runServiceCommand({ ...plan.statusCommand, tolerateFailure: true });
|
|
82753
|
+
if (result.status !== 0) {
|
|
82754
|
+
process.stdout.write(`unknown
|
|
82755
|
+
${result.output}
|
|
82756
|
+
`);
|
|
82757
|
+
return;
|
|
82758
|
+
}
|
|
82759
|
+
process.stdout.write(`${result.output}
|
|
82760
|
+
`);
|
|
82761
|
+
}
|
|
82762
|
+
|
|
82763
|
+
// src/install-command.ts
|
|
82764
|
+
async function runInstallCommand(commandArgs) {
|
|
82765
|
+
bindConfigPath(commandArgs);
|
|
82766
|
+
const configured = readConfig();
|
|
82767
|
+
const configurationMode = resolveInstallConfigurationMode(commandArgs, configured);
|
|
82768
|
+
if (configurationMode === "setup") await setupDaemon(commandArgs);
|
|
82769
|
+
if (configurationMode === "login") await loginWithDeviceCode(commandArgs);
|
|
82770
|
+
installDaemonService(commandArgs);
|
|
82771
|
+
runMcpIntegrationCommand(["reconcile", ...commandArgs]);
|
|
82772
|
+
}
|
|
82773
|
+
|
|
82774
|
+
// src/lifecycle-logger.ts
|
|
82775
|
+
var AgentLifecycleLogger = class _AgentLifecycleLogger {
|
|
82776
|
+
context;
|
|
82777
|
+
constructor(context = {}) {
|
|
82778
|
+
this.context = normalizeContext(context);
|
|
82779
|
+
}
|
|
82780
|
+
setContext(context) {
|
|
82781
|
+
this.context = normalizeContext({ ...this.context, ...context });
|
|
82782
|
+
}
|
|
82783
|
+
child(context) {
|
|
82784
|
+
return new _AgentLifecycleLogger({ ...this.context, ...context });
|
|
82785
|
+
}
|
|
82786
|
+
debug(event, fields = {}) {
|
|
82787
|
+
this.log("debug", event, fields);
|
|
82788
|
+
}
|
|
82789
|
+
info(event, fields = {}) {
|
|
82790
|
+
this.log("info", event, fields);
|
|
82791
|
+
}
|
|
82792
|
+
warn(event, fields = {}) {
|
|
82793
|
+
this.log("warn", event, fields);
|
|
82794
|
+
}
|
|
82795
|
+
error(event, fields = {}) {
|
|
82796
|
+
this.log("error", event, fields);
|
|
82797
|
+
}
|
|
82798
|
+
log(level, event, fields) {
|
|
82799
|
+
const record2 = omitUndefined({
|
|
82800
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
82801
|
+
level,
|
|
82802
|
+
component: "agent-manager",
|
|
82803
|
+
event,
|
|
82804
|
+
...this.context,
|
|
82805
|
+
...normalizeFields(fields)
|
|
82806
|
+
});
|
|
82807
|
+
console[level](JSON.stringify(record2));
|
|
82808
|
+
}
|
|
82809
|
+
};
|
|
82810
|
+
function lifecycleContextFromEnv(env) {
|
|
82811
|
+
return normalizeContext({
|
|
82812
|
+
taskId: env.ALAN_TASK_ID,
|
|
82813
|
+
conversationId: env.ALAN_SESSION_ID,
|
|
82814
|
+
runId: env.ALAN_RUN_ID,
|
|
82815
|
+
sandboxId: env.ALAN_SANDBOX_ID,
|
|
82816
|
+
provider: env.ALAN_SANDBOX_PROVIDER,
|
|
82817
|
+
backendKind: env.ALAN_BACKEND_KIND,
|
|
82818
|
+
agentVersion: AGENT_VERSION
|
|
82819
|
+
});
|
|
82820
|
+
}
|
|
82821
|
+
function normalizeContext(context) {
|
|
82822
|
+
return omitUndefined({
|
|
82823
|
+
...context,
|
|
82824
|
+
agentVersion: context.agentVersion ?? AGENT_VERSION
|
|
82825
|
+
});
|
|
82826
|
+
}
|
|
82827
|
+
function normalizeFields(fields) {
|
|
82828
|
+
const normalized = {};
|
|
82829
|
+
for (const [key, value2] of Object.entries(fields)) {
|
|
82830
|
+
if (value2 instanceof Error) {
|
|
82831
|
+
normalized[key] = {
|
|
82832
|
+
name: value2.name,
|
|
82833
|
+
message: value2.message,
|
|
82834
|
+
stack: value2.stack
|
|
82835
|
+
};
|
|
82836
|
+
} else {
|
|
82837
|
+
normalized[key] = value2;
|
|
82838
|
+
}
|
|
82839
|
+
}
|
|
82840
|
+
return normalized;
|
|
82841
|
+
}
|
|
82842
|
+
function omitUndefined(record2) {
|
|
82843
|
+
return Object.fromEntries(Object.entries(record2).filter(([, value2]) => value2 !== void 0));
|
|
82844
|
+
}
|
|
82845
|
+
|
|
82846
|
+
// ../../node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs
|
|
82847
|
+
var __create3 = Object.create;
|
|
82848
|
+
var __defProp3 = Object.defineProperty;
|
|
82849
|
+
var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
|
|
82850
|
+
var __getOwnPropNames3 = Object.getOwnPropertyNames;
|
|
82851
|
+
var __getProtoOf3 = Object.getPrototypeOf;
|
|
82852
|
+
var __hasOwnProp3 = Object.prototype.hasOwnProperty;
|
|
82853
|
+
var __commonJSMin2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
82854
|
+
var __exportAll2 = (all, symbols) => {
|
|
82855
|
+
let target = {};
|
|
82856
|
+
for (var name in all) {
|
|
82857
|
+
__defProp3(target, name, {
|
|
82858
|
+
get: all[name],
|
|
82859
|
+
enumerable: true
|
|
82860
|
+
});
|
|
82861
|
+
}
|
|
82862
|
+
if (symbols) {
|
|
82863
|
+
__defProp3(target, Symbol.toStringTag, { value: "Module" });
|
|
82864
|
+
}
|
|
82865
|
+
return target;
|
|
82866
|
+
};
|
|
82867
|
+
var __copyProps3 = (to, from, except, desc) => {
|
|
82868
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
82869
|
+
for (var keys = __getOwnPropNames3(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
82870
|
+
key = keys[i];
|
|
82871
|
+
if (!__hasOwnProp3.call(to, key) && key !== except) {
|
|
82872
|
+
__defProp3(to, key, {
|
|
82873
|
+
get: ((k) => from[k]).bind(null, key),
|
|
82874
|
+
enumerable: !(desc = __getOwnPropDesc3(from, key)) || desc.enumerable
|
|
82875
|
+
});
|
|
82876
|
+
}
|
|
82877
|
+
}
|
|
82878
|
+
}
|
|
82879
|
+
return to;
|
|
82880
|
+
};
|
|
82881
|
+
var __toESM3 = (mod, isNodeMode, target) => (target = mod != null ? __create3(__getProtoOf3(mod)) : {}, __copyProps3(isNodeMode || !mod || !mod.__esModule ? __defProp3(target, "default", {
|
|
82882
|
+
value: mod,
|
|
82883
|
+
enumerable: true
|
|
82884
|
+
}) : target, mod));
|
|
82885
|
+
|
|
82886
|
+
// ../../node_modules/@modelcontextprotocol/server/dist/dialects-DoSzNhcb.mjs
|
|
82887
|
+
var DRAFT_2020_12_URIS2 = /* @__PURE__ */ new Set(["https://json-schema.org/draft/2020-12/schema", "http://json-schema.org/draft/2020-12/schema"]);
|
|
82888
|
+
var DRAFT_2019_09_URIS2 = /* @__PURE__ */ new Set(["https://json-schema.org/draft/2019-09/schema", "http://json-schema.org/draft/2019-09/schema"]);
|
|
82889
|
+
var DRAFT_07_URIS2 = /* @__PURE__ */ new Set(["https://json-schema.org/draft-07/schema", "http://json-schema.org/draft-07/schema"]);
|
|
82890
|
+
var DRAFT_06_URIS2 = /* @__PURE__ */ new Set(["https://json-schema.org/draft-06/schema", "http://json-schema.org/draft-06/schema"]);
|
|
82891
|
+
function declares2019Dialect2($schema) {
|
|
82892
|
+
return typeof $schema === "string" && DRAFT_2019_09_URIS2.has($schema.replace(/#$/, ""));
|
|
82893
|
+
}
|
|
82894
|
+
function declaredDialect2(schema, remedy) {
|
|
82895
|
+
if (!("$schema" in schema) || typeof schema.$schema !== "string") return "2020-12";
|
|
82896
|
+
const declared = schema.$schema.replace(/#$/, "");
|
|
82897
|
+
if (DRAFT_2020_12_URIS2.has(declared)) return "2020-12";
|
|
82898
|
+
if (DRAFT_2019_09_URIS2.has(declared)) return "2019-09";
|
|
82899
|
+
if (DRAFT_07_URIS2.has(declared) || DRAFT_06_URIS2.has(declared)) return "draft-7";
|
|
82900
|
+
throw new Error(`JSON Schema declares an unsupported dialect ("$schema": "${schema.$schema.slice(0, 200)}"). The default validator supports JSON Schema 2020-12, 2019-09, draft-07, and draft-06; ${remedy}`);
|
|
82901
|
+
}
|
|
82902
|
+
|
|
82903
|
+
// ../../node_modules/@modelcontextprotocol/server/dist/src-CX2iR2pK.mjs
|
|
82904
|
+
var BRANDS2 = /* @__PURE__ */ Symbol.for("mcp.sdk.errorBrands");
|
|
82905
|
+
function stampErrorBrands2(instance, ctor) {
|
|
82906
|
+
const brands = /* @__PURE__ */ new Set();
|
|
82907
|
+
let current = ctor;
|
|
82908
|
+
while (typeof current === "function") {
|
|
82909
|
+
const brand = current.mcpBrand;
|
|
82910
|
+
if (Object.prototype.hasOwnProperty.call(current, "mcpBrand") && typeof brand === "string") brands.add(brand);
|
|
82911
|
+
current = Object.getPrototypeOf(current);
|
|
82912
|
+
}
|
|
82913
|
+
if (brands.size === 0) return;
|
|
82914
|
+
Object.defineProperty(instance, BRANDS2, {
|
|
82915
|
+
value: brands,
|
|
82916
|
+
enumerable: false,
|
|
82917
|
+
configurable: true
|
|
82918
|
+
});
|
|
82919
|
+
}
|
|
82920
|
+
function brandedHasInstance2(cls, value2) {
|
|
82921
|
+
try {
|
|
82922
|
+
if (typeof value2 === "object" && value2 !== null && Object.prototype.hasOwnProperty.call(cls, "mcpBrand") && typeof cls.mcpBrand === "string" && Object.prototype.hasOwnProperty.call(value2, BRANDS2)) {
|
|
82923
|
+
const carried = value2[BRANDS2];
|
|
82924
|
+
if (carried && typeof carried.has === "function" && carried.has(cls.mcpBrand)) return true;
|
|
82925
|
+
}
|
|
82926
|
+
} catch {
|
|
82927
|
+
}
|
|
82928
|
+
return Function.prototype[Symbol.hasInstance].call(cls, value2);
|
|
82929
|
+
}
|
|
82930
|
+
var OAuthError3 = class OAuthError4 extends Error {
|
|
82931
|
+
static {
|
|
82306
82932
|
Object.defineProperty(this, "mcpBrand", { value: "mcp.OAuthError" });
|
|
82307
82933
|
}
|
|
82308
82934
|
static [Symbol.hasInstance](value2) {
|
|
@@ -94584,27 +95210,27 @@ async function runMcpStdioProxy(env = process.env, local = new StdioServerTransp
|
|
|
94584
95210
|
|
|
94585
95211
|
// src/native-hook-command.ts
|
|
94586
95212
|
var import_node_crypto21 = require("crypto");
|
|
94587
|
-
var
|
|
94588
|
-
var
|
|
94589
|
-
var
|
|
95213
|
+
var import_node_fs27 = require("fs");
|
|
95214
|
+
var import_node_os17 = require("os");
|
|
95215
|
+
var import_node_path29 = require("path");
|
|
94590
95216
|
|
|
94591
95217
|
// src/native-project-config.ts
|
|
94592
|
-
var
|
|
94593
|
-
var
|
|
95218
|
+
var import_node_fs26 = require("fs");
|
|
95219
|
+
var import_node_path28 = require("path");
|
|
94594
95220
|
var MAX_ALAN_PROJECT_CONFIG_BYTES = 64 * 1024;
|
|
94595
95221
|
var ORGANIZATION_SLUG_PATTERN = /^[a-z0-9-]+$/;
|
|
94596
95222
|
var TEAM_IDENTIFIER_PATTERN = /^[A-Z0-9]{2,4}$/i;
|
|
94597
95223
|
function readAlanProjectPin(cwd) {
|
|
94598
95224
|
let fd;
|
|
94599
95225
|
try {
|
|
94600
|
-
fd = (0,
|
|
94601
|
-
(0,
|
|
94602
|
-
|
|
95226
|
+
fd = (0, import_node_fs26.openSync)(
|
|
95227
|
+
(0, import_node_path28.join)(cwd, "alan.json"),
|
|
95228
|
+
import_node_fs26.constants.O_RDONLY | import_node_fs26.constants.O_NONBLOCK | (import_node_fs26.constants.O_NOFOLLOW ?? 0)
|
|
94603
95229
|
);
|
|
94604
|
-
const stat2 = (0,
|
|
95230
|
+
const stat2 = (0, import_node_fs26.fstatSync)(fd);
|
|
94605
95231
|
if (!stat2.isFile() || stat2.size > MAX_ALAN_PROJECT_CONFIG_BYTES) return void 0;
|
|
94606
95232
|
const buffer = Buffer.allocUnsafe(MAX_ALAN_PROJECT_CONFIG_BYTES + 1);
|
|
94607
|
-
const bytesRead = (0,
|
|
95233
|
+
const bytesRead = (0, import_node_fs26.readSync)(fd, buffer, 0, buffer.byteLength, 0);
|
|
94608
95234
|
if (bytesRead > MAX_ALAN_PROJECT_CONFIG_BYTES) return void 0;
|
|
94609
95235
|
const parsed = JSON.parse(buffer.subarray(0, bytesRead).toString("utf8"));
|
|
94610
95236
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
@@ -94620,7 +95246,7 @@ function readAlanProjectPin(cwd) {
|
|
|
94620
95246
|
} finally {
|
|
94621
95247
|
if (fd !== void 0) {
|
|
94622
95248
|
try {
|
|
94623
|
-
(0,
|
|
95249
|
+
(0, import_node_fs26.closeSync)(fd);
|
|
94624
95250
|
} catch {
|
|
94625
95251
|
}
|
|
94626
95252
|
}
|
|
@@ -94859,19 +95485,19 @@ function nonNegativeIntegerField(payload, ...names) {
|
|
|
94859
95485
|
return void 0;
|
|
94860
95486
|
}
|
|
94861
95487
|
function resolveCodexSessionIdFromTranscriptPath(transcriptPath) {
|
|
94862
|
-
const fileName = (0,
|
|
95488
|
+
const fileName = (0, import_node_path29.basename)(transcriptPath);
|
|
94863
95489
|
const match = /^rollout-.*-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i.exec(
|
|
94864
95490
|
fileName
|
|
94865
95491
|
);
|
|
94866
95492
|
return match?.[1];
|
|
94867
95493
|
}
|
|
94868
|
-
function resolveKimiTranscriptPath(externalSessionId, kimiHomeDir = process.env.KIMI_CODE_HOME?.trim() || (0,
|
|
94869
|
-
if ((0,
|
|
94870
|
-
const sessionsDir = (0,
|
|
94871
|
-
if (!(0,
|
|
94872
|
-
for (const workspace of (0,
|
|
95494
|
+
function resolveKimiTranscriptPath(externalSessionId, kimiHomeDir = process.env.KIMI_CODE_HOME?.trim() || (0, import_node_path29.join)((0, import_node_os17.homedir)(), ".kimi-code")) {
|
|
95495
|
+
if ((0, import_node_path29.basename)(externalSessionId) !== externalSessionId) return void 0;
|
|
95496
|
+
const sessionsDir = (0, import_node_path29.join)(kimiHomeDir, "sessions");
|
|
95497
|
+
if (!(0, import_node_fs27.existsSync)(sessionsDir)) return void 0;
|
|
95498
|
+
for (const workspace of (0, import_node_fs27.readdirSync)(sessionsDir, { withFileTypes: true })) {
|
|
94873
95499
|
if (!workspace.isDirectory()) continue;
|
|
94874
|
-
const transcriptPath = (0,
|
|
95500
|
+
const transcriptPath = (0, import_node_path29.join)(
|
|
94875
95501
|
sessionsDir,
|
|
94876
95502
|
workspace.name,
|
|
94877
95503
|
externalSessionId,
|
|
@@ -94879,7 +95505,7 @@ function resolveKimiTranscriptPath(externalSessionId, kimiHomeDir = process.env.
|
|
|
94879
95505
|
"main",
|
|
94880
95506
|
"wire.jsonl"
|
|
94881
95507
|
);
|
|
94882
|
-
if ((0,
|
|
95508
|
+
if ((0, import_node_fs27.existsSync)(transcriptPath)) return transcriptPath;
|
|
94883
95509
|
}
|
|
94884
95510
|
return void 0;
|
|
94885
95511
|
}
|
|
@@ -94914,7 +95540,7 @@ function parseNativeHookEnvelope(input2) {
|
|
|
94914
95540
|
const rawHookEvent = input2.hookEvent ?? stringField4(payload, "hook_event_name", "hookEvent", "hookEventName", "type") ?? "notification";
|
|
94915
95541
|
const eventType = normalizeHookEvent(rawHookEvent);
|
|
94916
95542
|
const cwd = stringField4(payload, "cwd", "working_directory", "workingDirectory") ?? firstStringArrayField(payload, "workspace_roots", "workspaceRoots");
|
|
94917
|
-
const resolvedCwd = cwd ? (0,
|
|
95543
|
+
const resolvedCwd = cwd ? (0, import_node_path29.resolve)(cwd) : void 0;
|
|
94918
95544
|
const transcriptPath = eventType === "subagent_start" || eventType === "subagent_end" ? stringField4(
|
|
94919
95545
|
payload,
|
|
94920
95546
|
"agent_transcript_path",
|
|
@@ -94960,7 +95586,7 @@ function parseNativeHookEnvelope(input2) {
|
|
|
94960
95586
|
...(eventType === "subagent_start" || eventType === "subagent_end") && parentSessionId ? { parentExternalSessionId: parentSessionId } : {},
|
|
94961
95587
|
...resolvedCwd ? { cwd: resolvedCwd } : {},
|
|
94962
95588
|
...projectPin,
|
|
94963
|
-
...transcriptPath ? { transcriptPath: (0,
|
|
95589
|
+
...transcriptPath ? { transcriptPath: (0, import_node_path29.resolve)(transcriptPath) } : {},
|
|
94964
95590
|
...cursor ? { sourceCursor: cursor } : {},
|
|
94965
95591
|
providerPayload
|
|
94966
95592
|
};
|
|
@@ -95007,7 +95633,7 @@ function readBoundedHookPayload(fd = 0, maxBytes = MAX_NATIVE_HOOK_STDIN_BYTES)
|
|
|
95007
95633
|
let totalBytes = 0;
|
|
95008
95634
|
while (true) {
|
|
95009
95635
|
const chunk = Buffer.allocUnsafe(Math.min(64 * 1024, maxBytes + 1 - totalBytes));
|
|
95010
|
-
const bytesRead = (0,
|
|
95636
|
+
const bytesRead = (0, import_node_fs27.readSync)(fd, chunk, 0, chunk.byteLength, null);
|
|
95011
95637
|
if (bytesRead === 0) break;
|
|
95012
95638
|
totalBytes += bytesRead;
|
|
95013
95639
|
if (totalBytes > maxBytes) throw new Error(`hook input exceeds ${maxBytes} bytes`);
|
|
@@ -95090,7 +95716,7 @@ function collectNativeIntegrationStatus(args = []) {
|
|
|
95090
95716
|
const config2 = readConfig();
|
|
95091
95717
|
const configPath = getConfigPath();
|
|
95092
95718
|
const env = getDaemonCliEnvironment();
|
|
95093
|
-
const homeDir = (0,
|
|
95719
|
+
const homeDir = (0, import_node_os17.homedir)();
|
|
95094
95720
|
return NATIVE_SESSION_PROVIDER_CAPABILITIES.map((capability) => ({
|
|
95095
95721
|
provider: capability.providerKind,
|
|
95096
95722
|
command: capability.command,
|
|
@@ -95119,7 +95745,7 @@ function decodeResumeFallbackContext(encoded) {
|
|
|
95119
95745
|
}
|
|
95120
95746
|
|
|
95121
95747
|
// src/sandbox.ts
|
|
95122
|
-
var
|
|
95748
|
+
var import_node_os18 = require("os");
|
|
95123
95749
|
|
|
95124
95750
|
// src/execution-activity-tracker.ts
|
|
95125
95751
|
var ExecutionActivityTracker = class {
|
|
@@ -95733,7 +96359,7 @@ var agentProbeAckSchema = external_exports.object({
|
|
|
95733
96359
|
|
|
95734
96360
|
// src/sandbox-outbox.ts
|
|
95735
96361
|
var import_node_crypto23 = require("crypto");
|
|
95736
|
-
var
|
|
96362
|
+
var import_node_fs28 = require("fs");
|
|
95737
96363
|
function deriveSandboxOutboxKey(sessionToken) {
|
|
95738
96364
|
if (!sessionToken) {
|
|
95739
96365
|
throw new Error("sandbox event outbox requires ALAN_SESSION_TOKEN for key derivation");
|
|
@@ -95754,24 +96380,24 @@ function assertValidOutboxKey(key, path2) {
|
|
|
95754
96380
|
}
|
|
95755
96381
|
function loadOrCreateSandboxOutboxKey(input2) {
|
|
95756
96382
|
const keyPath = sandboxOutboxKeyPath(input2.spoolPath);
|
|
95757
|
-
if ((0,
|
|
95758
|
-
(0,
|
|
95759
|
-
return assertValidOutboxKey((0,
|
|
96383
|
+
if ((0, import_node_fs28.existsSync)(keyPath)) {
|
|
96384
|
+
(0, import_node_fs28.chmodSync)(keyPath, 384);
|
|
96385
|
+
return assertValidOutboxKey((0, import_node_fs28.readFileSync)(keyPath, "utf8").trim(), keyPath);
|
|
95760
96386
|
}
|
|
95761
96387
|
const initialKey = deriveSandboxOutboxKey(input2.sessionToken);
|
|
95762
96388
|
try {
|
|
95763
|
-
(0,
|
|
96389
|
+
(0, import_node_fs28.writeFileSync)(keyPath, initialKey, { encoding: "utf8", flag: "wx", mode: 384 });
|
|
95764
96390
|
return initialKey;
|
|
95765
96391
|
} catch (error61) {
|
|
95766
96392
|
if (error61.code !== "EEXIST") throw error61;
|
|
95767
|
-
(0,
|
|
95768
|
-
return assertValidOutboxKey((0,
|
|
96393
|
+
(0, import_node_fs28.chmodSync)(keyPath, 384);
|
|
96394
|
+
return assertValidOutboxKey((0, import_node_fs28.readFileSync)(keyPath, "utf8").trim(), keyPath);
|
|
95769
96395
|
}
|
|
95770
96396
|
}
|
|
95771
96397
|
function quarantineUnusableOutbox(path2) {
|
|
95772
96398
|
const suffix = `corrupt-${Date.now()}-${process.pid}`;
|
|
95773
96399
|
for (const candidate of [path2, eventJournalDir(path2)]) {
|
|
95774
|
-
if ((0,
|
|
96400
|
+
if ((0, import_node_fs28.existsSync)(candidate)) (0, import_node_fs28.renameSync)(candidate, `${candidate}.${suffix}`);
|
|
95775
96401
|
}
|
|
95776
96402
|
}
|
|
95777
96403
|
function createSandboxEventOutbox(input2) {
|
|
@@ -96431,7 +97057,7 @@ async function runSandbox(config2) {
|
|
|
96431
97057
|
}
|
|
96432
97058
|
const presenter = new WebPresenter(wsClient, config2.sessionId, config2.projectPath);
|
|
96433
97059
|
presenter.setSuppressSessionLifecycle(true);
|
|
96434
|
-
const runtimeSkillManager = await RuntimeSkillManager.open({ homeDirectory: (0,
|
|
97060
|
+
const runtimeSkillManager = await RuntimeSkillManager.open({ homeDirectory: (0, import_node_os18.homedir)() });
|
|
96435
97061
|
let lastProviderSessionId = config2.providerSessionId;
|
|
96436
97062
|
let resumeFallbackContext = config2.resumeFallbackContext;
|
|
96437
97063
|
let activeBackendKind = config2.backendKind || "claude_cli";
|
|
@@ -96728,616 +97354,6 @@ async function runSandbox(config2) {
|
|
|
96728
97354
|
wsClient.close();
|
|
96729
97355
|
}
|
|
96730
97356
|
|
|
96731
|
-
// src/service-manager.ts
|
|
96732
|
-
var import_node_child_process9 = require("child_process");
|
|
96733
|
-
var import_node_fs28 = require("fs");
|
|
96734
|
-
var import_node_os18 = require("os");
|
|
96735
|
-
var import_node_path29 = require("path");
|
|
96736
|
-
var SERVICE_LABEL = "ai.tryalan.agent";
|
|
96737
|
-
var SYSTEMD_UNIT = "alan-agent.service";
|
|
96738
|
-
var WINDOWS_TASK = "Alan Agent";
|
|
96739
|
-
function xml(value2) {
|
|
96740
|
-
return value2.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
96741
|
-
}
|
|
96742
|
-
function systemdArg(value2) {
|
|
96743
|
-
return `"${value2.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
|
|
96744
|
-
}
|
|
96745
|
-
function powershellLiteral(value2) {
|
|
96746
|
-
return `'${value2.replaceAll("'", "''")}'`;
|
|
96747
|
-
}
|
|
96748
|
-
function serviceNames(profile) {
|
|
96749
|
-
if (profile === "production") {
|
|
96750
|
-
return { launchd: SERVICE_LABEL, systemd: SYSTEMD_UNIT, windows: WINDOWS_TASK };
|
|
96751
|
-
}
|
|
96752
|
-
const suffix = profile === "custom" ? "prod" : profile;
|
|
96753
|
-
const title = `${suffix[0]?.toUpperCase()}${suffix.slice(1)}`;
|
|
96754
|
-
return {
|
|
96755
|
-
launchd: `${SERVICE_LABEL}.${suffix}`,
|
|
96756
|
-
systemd: `alan-agent-${suffix}.service`,
|
|
96757
|
-
windows: `${WINDOWS_TASK} ${title}`
|
|
96758
|
-
};
|
|
96759
|
-
}
|
|
96760
|
-
function buildDaemonServicePlan(input2) {
|
|
96761
|
-
const daemonArgs = [input2.nodeExecutable, input2.cliEntry, "daemon", "--profile", input2.profile];
|
|
96762
|
-
const names = serviceNames(input2.profile);
|
|
96763
|
-
if (input2.platform === "darwin") {
|
|
96764
|
-
const userId = input2.userId ?? process.getuid?.();
|
|
96765
|
-
if (userId === void 0) throw new Error("Cannot determine the current macOS user ID");
|
|
96766
|
-
const domain2 = `gui/${userId}`;
|
|
96767
|
-
const serviceTarget = `${domain2}/${names.launchd}`;
|
|
96768
|
-
const manifestPath = (0, import_node_path29.join)(input2.homeDir, "Library", "LaunchAgents", `${names.launchd}.plist`);
|
|
96769
|
-
const logDir = (0, import_node_path29.join)(resolveAgentConfigDirectory(input2.profile, input2.homeDir), "logs");
|
|
96770
|
-
const programArguments = daemonArgs.map((arg) => ` <string>${xml(arg)}</string>`).join("\n");
|
|
96771
|
-
const environmentEntries = Object.entries(input2.environment ?? {}).map(([key, value2]) => ` <key>${xml(key)}</key>
|
|
96772
|
-
<string>${xml(value2)}</string>`).join("\n");
|
|
96773
|
-
const environmentBlock = environmentEntries ? ` <key>EnvironmentVariables</key>
|
|
96774
|
-
<dict>
|
|
96775
|
-
${environmentEntries}
|
|
96776
|
-
</dict>
|
|
96777
|
-
` : "";
|
|
96778
|
-
const manifest = `<?xml version="1.0" encoding="UTF-8"?>
|
|
96779
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
96780
|
-
<plist version="1.0">
|
|
96781
|
-
<dict>
|
|
96782
|
-
<key>Label</key>
|
|
96783
|
-
<string>${names.launchd}</string>
|
|
96784
|
-
<key>ProgramArguments</key>
|
|
96785
|
-
<array>
|
|
96786
|
-
${programArguments}
|
|
96787
|
-
</array>
|
|
96788
|
-
${environmentBlock} <key>RunAtLoad</key>
|
|
96789
|
-
<true/>
|
|
96790
|
-
<key>KeepAlive</key>
|
|
96791
|
-
<dict>
|
|
96792
|
-
<key>SuccessfulExit</key>
|
|
96793
|
-
<false/>
|
|
96794
|
-
</dict>
|
|
96795
|
-
<key>ThrottleInterval</key>
|
|
96796
|
-
<integer>5</integer>
|
|
96797
|
-
<key>StandardOutPath</key>
|
|
96798
|
-
<string>${xml((0, import_node_path29.join)(logDir, "daemon.log"))}</string>
|
|
96799
|
-
<key>StandardErrorPath</key>
|
|
96800
|
-
<string>${xml((0, import_node_path29.join)(logDir, "daemon-error.log"))}</string>
|
|
96801
|
-
</dict>
|
|
96802
|
-
</plist>
|
|
96803
|
-
`;
|
|
96804
|
-
return {
|
|
96805
|
-
platform: "darwin",
|
|
96806
|
-
manifestPath,
|
|
96807
|
-
manifest,
|
|
96808
|
-
logDirectory: logDir,
|
|
96809
|
-
loadDefinitionCommands: [
|
|
96810
|
-
{
|
|
96811
|
-
command: "launchctl",
|
|
96812
|
-
args: ["bootstrap", domain2, manifestPath],
|
|
96813
|
-
tolerateFailure: true
|
|
96814
|
-
}
|
|
96815
|
-
],
|
|
96816
|
-
reloadDefinitionCommands: [
|
|
96817
|
-
{
|
|
96818
|
-
command: "launchctl",
|
|
96819
|
-
args: ["bootout", domain2, manifestPath],
|
|
96820
|
-
tolerateFailure: true
|
|
96821
|
-
},
|
|
96822
|
-
{
|
|
96823
|
-
command: "launchctl",
|
|
96824
|
-
args: ["bootstrap", domain2, manifestPath],
|
|
96825
|
-
tolerateFailure: false
|
|
96826
|
-
}
|
|
96827
|
-
],
|
|
96828
|
-
enableCommands: [
|
|
96829
|
-
{
|
|
96830
|
-
command: "launchctl",
|
|
96831
|
-
args: ["enable", serviceTarget],
|
|
96832
|
-
tolerateFailure: true
|
|
96833
|
-
}
|
|
96834
|
-
],
|
|
96835
|
-
startCommands: [
|
|
96836
|
-
{
|
|
96837
|
-
command: "launchctl",
|
|
96838
|
-
args: ["kickstart", serviceTarget],
|
|
96839
|
-
tolerateFailure: false
|
|
96840
|
-
}
|
|
96841
|
-
],
|
|
96842
|
-
stopCommands: [
|
|
96843
|
-
{
|
|
96844
|
-
command: "launchctl",
|
|
96845
|
-
args: ["kill", "SIGTERM", serviceTarget],
|
|
96846
|
-
tolerateFailure: true
|
|
96847
|
-
}
|
|
96848
|
-
],
|
|
96849
|
-
replaceCommands: [
|
|
96850
|
-
{
|
|
96851
|
-
command: "launchctl",
|
|
96852
|
-
args: ["bootout", domain2, manifestPath],
|
|
96853
|
-
tolerateFailure: true
|
|
96854
|
-
},
|
|
96855
|
-
{
|
|
96856
|
-
command: "launchctl",
|
|
96857
|
-
args: ["bootstrap", domain2, manifestPath],
|
|
96858
|
-
tolerateFailure: false
|
|
96859
|
-
},
|
|
96860
|
-
{
|
|
96861
|
-
command: "launchctl",
|
|
96862
|
-
args: ["kickstart", "-k", serviceTarget],
|
|
96863
|
-
tolerateFailure: false
|
|
96864
|
-
}
|
|
96865
|
-
],
|
|
96866
|
-
uninstallCommands: [
|
|
96867
|
-
{
|
|
96868
|
-
command: "launchctl",
|
|
96869
|
-
args: ["bootout", domain2, manifestPath],
|
|
96870
|
-
tolerateFailure: true
|
|
96871
|
-
}
|
|
96872
|
-
],
|
|
96873
|
-
statusCommand: {
|
|
96874
|
-
command: "launchctl",
|
|
96875
|
-
args: ["print", serviceTarget],
|
|
96876
|
-
tolerateFailure: true
|
|
96877
|
-
},
|
|
96878
|
-
isActiveCommand: {
|
|
96879
|
-
command: "launchctl",
|
|
96880
|
-
args: ["print", serviceTarget],
|
|
96881
|
-
tolerateFailure: true
|
|
96882
|
-
},
|
|
96883
|
-
lingerStatusCommand: null
|
|
96884
|
-
};
|
|
96885
|
-
}
|
|
96886
|
-
if (input2.platform === "linux") {
|
|
96887
|
-
const manifestPath = (0, import_node_path29.join)(input2.homeDir, ".config", "systemd", "user", names.systemd);
|
|
96888
|
-
const environmentLines = Object.entries(input2.environment ?? {}).map(([key, value2]) => `Environment=${systemdArg(`${key}=${value2}`)}`).join("\n");
|
|
96889
|
-
const manifest = `[Unit]
|
|
96890
|
-
Description=Alan local agent daemon
|
|
96891
|
-
After=network-online.target
|
|
96892
|
-
Wants=network-online.target
|
|
96893
|
-
StartLimitIntervalSec=300
|
|
96894
|
-
StartLimitBurst=3
|
|
96895
|
-
|
|
96896
|
-
[Service]
|
|
96897
|
-
Type=simple
|
|
96898
|
-
${environmentLines ? `${environmentLines}
|
|
96899
|
-
` : ""}ExecStart=${daemonArgs.map(systemdArg).join(" ")}
|
|
96900
|
-
Restart=on-failure
|
|
96901
|
-
RestartSec=5
|
|
96902
|
-
|
|
96903
|
-
[Install]
|
|
96904
|
-
WantedBy=default.target
|
|
96905
|
-
`;
|
|
96906
|
-
return {
|
|
96907
|
-
platform: "linux",
|
|
96908
|
-
manifestPath,
|
|
96909
|
-
manifest,
|
|
96910
|
-
logDirectory: null,
|
|
96911
|
-
loadDefinitionCommands: [
|
|
96912
|
-
{
|
|
96913
|
-
command: "systemctl",
|
|
96914
|
-
args: ["--user", "daemon-reload"],
|
|
96915
|
-
tolerateFailure: false
|
|
96916
|
-
}
|
|
96917
|
-
],
|
|
96918
|
-
reloadDefinitionCommands: [
|
|
96919
|
-
{
|
|
96920
|
-
command: "systemctl",
|
|
96921
|
-
args: ["--user", "daemon-reload"],
|
|
96922
|
-
tolerateFailure: false
|
|
96923
|
-
}
|
|
96924
|
-
],
|
|
96925
|
-
enableCommands: [
|
|
96926
|
-
{
|
|
96927
|
-
command: "systemctl",
|
|
96928
|
-
args: ["--user", "enable", names.systemd],
|
|
96929
|
-
tolerateFailure: false
|
|
96930
|
-
}
|
|
96931
|
-
],
|
|
96932
|
-
startCommands: [
|
|
96933
|
-
{
|
|
96934
|
-
command: "systemctl",
|
|
96935
|
-
args: ["--user", "start", names.systemd],
|
|
96936
|
-
tolerateFailure: false
|
|
96937
|
-
}
|
|
96938
|
-
],
|
|
96939
|
-
stopCommands: [
|
|
96940
|
-
{
|
|
96941
|
-
command: "systemctl",
|
|
96942
|
-
args: ["--user", "stop", names.systemd],
|
|
96943
|
-
tolerateFailure: true
|
|
96944
|
-
}
|
|
96945
|
-
],
|
|
96946
|
-
replaceCommands: [
|
|
96947
|
-
{
|
|
96948
|
-
command: "systemctl",
|
|
96949
|
-
args: ["--user", "daemon-reload"],
|
|
96950
|
-
tolerateFailure: false
|
|
96951
|
-
},
|
|
96952
|
-
{
|
|
96953
|
-
command: "systemctl",
|
|
96954
|
-
args: ["--user", "restart", names.systemd],
|
|
96955
|
-
tolerateFailure: false
|
|
96956
|
-
}
|
|
96957
|
-
],
|
|
96958
|
-
uninstallCommands: [
|
|
96959
|
-
{
|
|
96960
|
-
command: "systemctl",
|
|
96961
|
-
args: ["--user", "disable", "--now", names.systemd],
|
|
96962
|
-
tolerateFailure: true
|
|
96963
|
-
},
|
|
96964
|
-
{
|
|
96965
|
-
command: "systemctl",
|
|
96966
|
-
args: ["--user", "daemon-reload"],
|
|
96967
|
-
tolerateFailure: false
|
|
96968
|
-
}
|
|
96969
|
-
],
|
|
96970
|
-
statusCommand: {
|
|
96971
|
-
command: "systemctl",
|
|
96972
|
-
args: ["--user", "status", names.systemd, "--no-pager"],
|
|
96973
|
-
tolerateFailure: true
|
|
96974
|
-
},
|
|
96975
|
-
isActiveCommand: {
|
|
96976
|
-
command: "systemctl",
|
|
96977
|
-
args: ["--user", "is-active", names.systemd],
|
|
96978
|
-
tolerateFailure: true
|
|
96979
|
-
},
|
|
96980
|
-
lingerStatusCommand: {
|
|
96981
|
-
command: "loginctl",
|
|
96982
|
-
args: ["show-user", "$(id -un)", "-p", "Linger"],
|
|
96983
|
-
tolerateFailure: true
|
|
96984
|
-
}
|
|
96985
|
-
};
|
|
96986
|
-
}
|
|
96987
|
-
const environmentPrefix = Object.entries(input2.environment ?? {}).map(([key, value2]) => `$env:${key} = ${powershellLiteral(value2)}`).join("; ");
|
|
96988
|
-
const directArgument = [input2.cliEntry, "daemon", "--profile", input2.profile].map((part) => part.includes(" ") ? `"${part}"` : part).join(" ");
|
|
96989
|
-
const executable = powershellLiteral(environmentPrefix ? "powershell.exe" : input2.nodeExecutable);
|
|
96990
|
-
const argument = powershellLiteral(
|
|
96991
|
-
environmentPrefix ? `-NoProfile -NonInteractive -WindowStyle Hidden -Command "${environmentPrefix}; & ${powershellLiteral(input2.nodeExecutable)} ${powershellLiteral(input2.cliEntry)} daemon --profile ${input2.profile}"` : directArgument
|
|
96992
|
-
);
|
|
96993
|
-
const registerScript = [
|
|
96994
|
-
"$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name",
|
|
96995
|
-
`$action = New-ScheduledTaskAction -Execute ${executable} -Argument ${argument}`,
|
|
96996
|
-
"$trigger = New-ScheduledTaskTrigger -AtLogOn -User $currentUser",
|
|
96997
|
-
"$principal = New-ScheduledTaskPrincipal -UserId $currentUser -LogonType Interactive -RunLevel Limited",
|
|
96998
|
-
"$settings = New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -ExecutionTimeLimit ([TimeSpan]::Zero)",
|
|
96999
|
-
`Register-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Force | Out-Null`
|
|
97000
|
-
].join("; ");
|
|
97001
|
-
return {
|
|
97002
|
-
platform: "win32",
|
|
97003
|
-
manifestPath: null,
|
|
97004
|
-
manifest: null,
|
|
97005
|
-
logDirectory: null,
|
|
97006
|
-
loadDefinitionCommands: [
|
|
97007
|
-
{
|
|
97008
|
-
command: "powershell.exe",
|
|
97009
|
-
args: ["-NoProfile", "-NonInteractive", "-Command", registerScript],
|
|
97010
|
-
tolerateFailure: false
|
|
97011
|
-
}
|
|
97012
|
-
],
|
|
97013
|
-
reloadDefinitionCommands: [
|
|
97014
|
-
{
|
|
97015
|
-
command: "powershell.exe",
|
|
97016
|
-
args: ["-NoProfile", "-NonInteractive", "-Command", registerScript],
|
|
97017
|
-
tolerateFailure: false
|
|
97018
|
-
}
|
|
97019
|
-
],
|
|
97020
|
-
enableCommands: [],
|
|
97021
|
-
startCommands: [
|
|
97022
|
-
{
|
|
97023
|
-
command: "powershell.exe",
|
|
97024
|
-
args: [
|
|
97025
|
-
"-NoProfile",
|
|
97026
|
-
"-NonInteractive",
|
|
97027
|
-
"-Command",
|
|
97028
|
-
`Start-ScheduledTask -TaskName ${powershellLiteral(names.windows)}`
|
|
97029
|
-
],
|
|
97030
|
-
tolerateFailure: false
|
|
97031
|
-
}
|
|
97032
|
-
],
|
|
97033
|
-
stopCommands: [
|
|
97034
|
-
{
|
|
97035
|
-
command: "powershell.exe",
|
|
97036
|
-
args: [
|
|
97037
|
-
"-NoProfile",
|
|
97038
|
-
"-NonInteractive",
|
|
97039
|
-
"-Command",
|
|
97040
|
-
`Stop-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -ErrorAction SilentlyContinue`
|
|
97041
|
-
],
|
|
97042
|
-
tolerateFailure: true
|
|
97043
|
-
}
|
|
97044
|
-
],
|
|
97045
|
-
replaceCommands: [
|
|
97046
|
-
{
|
|
97047
|
-
command: "powershell.exe",
|
|
97048
|
-
args: [
|
|
97049
|
-
"-NoProfile",
|
|
97050
|
-
"-NonInteractive",
|
|
97051
|
-
"-Command",
|
|
97052
|
-
`${registerScript}; Start-ScheduledTask -TaskName ${powershellLiteral(names.windows)}`
|
|
97053
|
-
],
|
|
97054
|
-
tolerateFailure: false
|
|
97055
|
-
}
|
|
97056
|
-
],
|
|
97057
|
-
uninstallCommands: [
|
|
97058
|
-
{
|
|
97059
|
-
command: "powershell.exe",
|
|
97060
|
-
args: [
|
|
97061
|
-
"-NoProfile",
|
|
97062
|
-
"-NonInteractive",
|
|
97063
|
-
"-Command",
|
|
97064
|
-
`Unregister-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -Confirm:$false -ErrorAction SilentlyContinue`
|
|
97065
|
-
],
|
|
97066
|
-
tolerateFailure: true
|
|
97067
|
-
}
|
|
97068
|
-
],
|
|
97069
|
-
statusCommand: {
|
|
97070
|
-
command: "powershell.exe",
|
|
97071
|
-
args: [
|
|
97072
|
-
"-NoProfile",
|
|
97073
|
-
"-NonInteractive",
|
|
97074
|
-
"-Command",
|
|
97075
|
-
`Get-ScheduledTask -TaskName ${powershellLiteral(names.windows)} | Format-List TaskName,State`
|
|
97076
|
-
],
|
|
97077
|
-
tolerateFailure: true
|
|
97078
|
-
},
|
|
97079
|
-
isActiveCommand: {
|
|
97080
|
-
command: "powershell.exe",
|
|
97081
|
-
args: [
|
|
97082
|
-
"-NoProfile",
|
|
97083
|
-
"-NonInteractive",
|
|
97084
|
-
"-Command",
|
|
97085
|
-
`(Get-ScheduledTask -TaskName ${powershellLiteral(names.windows)} -ErrorAction SilentlyContinue).State`
|
|
97086
|
-
],
|
|
97087
|
-
tolerateFailure: true
|
|
97088
|
-
},
|
|
97089
|
-
lingerStatusCommand: null
|
|
97090
|
-
};
|
|
97091
|
-
}
|
|
97092
|
-
function resolveCurrentPlatform() {
|
|
97093
|
-
const currentPlatform = (0, import_node_os18.platform)();
|
|
97094
|
-
if (currentPlatform !== "darwin" && currentPlatform !== "linux" && currentPlatform !== "win32") {
|
|
97095
|
-
throw new Error(`Daemon service installation is not supported on ${currentPlatform}`);
|
|
97096
|
-
}
|
|
97097
|
-
return currentPlatform;
|
|
97098
|
-
}
|
|
97099
|
-
function currentServicePlan(args, runtime) {
|
|
97100
|
-
const currentPlatform = resolveCurrentPlatform();
|
|
97101
|
-
const profile = resolveEndpointProfileFromArgs(args);
|
|
97102
|
-
const cliEntry = runtime?.cliEntry ?? process.argv[1];
|
|
97103
|
-
if (!cliEntry) throw new Error("Cannot determine the alan-agent executable path");
|
|
97104
|
-
return buildDaemonServicePlan({
|
|
97105
|
-
platform: currentPlatform,
|
|
97106
|
-
homeDir: (0, import_node_os18.homedir)(),
|
|
97107
|
-
nodeExecutable: runtime?.executable ?? process.execPath,
|
|
97108
|
-
cliEntry: (0, import_node_path29.resolve)(cliEntry),
|
|
97109
|
-
profile,
|
|
97110
|
-
environment: runtime?.environment
|
|
97111
|
-
});
|
|
97112
|
-
}
|
|
97113
|
-
function writeManifestAtomic(path2, contents) {
|
|
97114
|
-
(0, import_node_fs28.mkdirSync)((0, import_node_path29.dirname)(path2), { recursive: true, mode: 448 });
|
|
97115
|
-
const pendingPath = `${path2}.pending-${process.pid}`;
|
|
97116
|
-
try {
|
|
97117
|
-
(0, import_node_fs28.writeFileSync)(pendingPath, contents, { mode: 384 });
|
|
97118
|
-
(0, import_node_fs28.chmodSync)(pendingPath, 384);
|
|
97119
|
-
(0, import_node_fs28.renameSync)(pendingPath, path2);
|
|
97120
|
-
} finally {
|
|
97121
|
-
(0, import_node_fs28.rmSync)(pendingPath, { force: true });
|
|
97122
|
-
}
|
|
97123
|
-
}
|
|
97124
|
-
function defaultReadManifest(path2) {
|
|
97125
|
-
if (!(0, import_node_fs28.existsSync)(path2)) return null;
|
|
97126
|
-
return (0, import_node_fs28.readFileSync)(path2, "utf8");
|
|
97127
|
-
}
|
|
97128
|
-
function runServiceCommand(command) {
|
|
97129
|
-
const result = (0, import_node_child_process9.spawnSync)(command.command, command.args, { encoding: "utf8", shell: false });
|
|
97130
|
-
const status = result.status ?? 1;
|
|
97131
|
-
const output2 = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
|
|
97132
|
-
if (status !== 0 && !command.tolerateFailure) {
|
|
97133
|
-
throw new Error(
|
|
97134
|
-
`Service command failed (${command.command} ${command.args.join(" ")}): ${output2 || `exit ${status}`}`
|
|
97135
|
-
);
|
|
97136
|
-
}
|
|
97137
|
-
return { status, output: output2 };
|
|
97138
|
-
}
|
|
97139
|
-
function defaultSleep(ms) {
|
|
97140
|
-
return new Promise((resolveSleep) => {
|
|
97141
|
-
setTimeout(resolveSleep, ms);
|
|
97142
|
-
});
|
|
97143
|
-
}
|
|
97144
|
-
function parseServiceHostState(servicePlatform, result) {
|
|
97145
|
-
const output2 = result.output;
|
|
97146
|
-
if (servicePlatform === "linux") {
|
|
97147
|
-
const trimmed = output2.trim().toLowerCase();
|
|
97148
|
-
if (trimmed === "inactive" || trimmed === "failed" || trimmed === "dead" || /\binactive\b/i.test(output2) || /\bfailed\b/i.test(output2)) {
|
|
97149
|
-
return "stopped";
|
|
97150
|
-
}
|
|
97151
|
-
}
|
|
97152
|
-
if (result.status !== 0) return "unknown";
|
|
97153
|
-
if (servicePlatform === "darwin") {
|
|
97154
|
-
if (/\bstate\s*=\s*running\b/i.test(output2)) return "running";
|
|
97155
|
-
if (/\bstate\s*=\s*(not running|waiting|stopped)\b/i.test(output2)) return "stopped";
|
|
97156
|
-
if (/\bpid\s*=\s*[1-9]\d*\b/i.test(output2)) return "running";
|
|
97157
|
-
if (/could not find service/i.test(output2)) return "stopped";
|
|
97158
|
-
return "unknown";
|
|
97159
|
-
}
|
|
97160
|
-
if (servicePlatform === "linux") {
|
|
97161
|
-
const trimmed = output2.trim().toLowerCase();
|
|
97162
|
-
if (trimmed === "active" || /\bactive\s*\(running\)/i.test(output2)) return "running";
|
|
97163
|
-
if (trimmed === "activating" || trimmed === "reloading") return "starting";
|
|
97164
|
-
return "unknown";
|
|
97165
|
-
}
|
|
97166
|
-
const stateMatch = output2.match(/\b(?:State|state)\s*[:=]\s*(\w+)/);
|
|
97167
|
-
const state = (stateMatch?.[1] ?? output2.trim()).toLowerCase();
|
|
97168
|
-
if (state === "running") return "running";
|
|
97169
|
-
if (state === "ready" || state === "disabled" || state === "queued") return "stopped";
|
|
97170
|
-
return "unknown";
|
|
97171
|
-
}
|
|
97172
|
-
function resolveEnsureDefinitionOutcome(input2) {
|
|
97173
|
-
if (!input2.definitionChanged) {
|
|
97174
|
-
return { changed: false, updatePending: false };
|
|
97175
|
-
}
|
|
97176
|
-
if (input2.hostState === "running" || input2.hostState === "starting") {
|
|
97177
|
-
return { changed: true, updatePending: true };
|
|
97178
|
-
}
|
|
97179
|
-
return { changed: true, updatePending: false };
|
|
97180
|
-
}
|
|
97181
|
-
function shouldStartOnInstall(hostState) {
|
|
97182
|
-
return hostState === "stopped";
|
|
97183
|
-
}
|
|
97184
|
-
function resolveUsername(options) {
|
|
97185
|
-
if (options?.username) return options.username;
|
|
97186
|
-
try {
|
|
97187
|
-
return (0, import_node_os18.userInfo)().username;
|
|
97188
|
-
} catch {
|
|
97189
|
-
return process.env.USER || process.env.USERNAME || "unknown";
|
|
97190
|
-
}
|
|
97191
|
-
}
|
|
97192
|
-
function buildLingerStatusCommand(username) {
|
|
97193
|
-
return {
|
|
97194
|
-
command: "loginctl",
|
|
97195
|
-
args: ["show-user", username, "-p", "Linger"],
|
|
97196
|
-
tolerateFailure: true
|
|
97197
|
-
};
|
|
97198
|
-
}
|
|
97199
|
-
function assertSystemdUserLingerEnabled(options = {}) {
|
|
97200
|
-
const username = resolveUsername(options);
|
|
97201
|
-
const run = options.runCommand ?? runServiceCommand;
|
|
97202
|
-
const result = run(buildLingerStatusCommand(username));
|
|
97203
|
-
if (result.status !== 0) {
|
|
97204
|
-
throw new Error(
|
|
97205
|
-
`Cannot verify systemd user linger for ${username} (loginctl failed). For durable headless VM boot run: sudo loginctl enable-linger ${username}`
|
|
97206
|
-
);
|
|
97207
|
-
}
|
|
97208
|
-
if (!/Linger=yes/i.test(result.output)) {
|
|
97209
|
-
throw new Error(
|
|
97210
|
-
`systemd user linger is disabled for ${username}. For durable headless VM boot run: sudo loginctl enable-linger ${username}`
|
|
97211
|
-
);
|
|
97212
|
-
}
|
|
97213
|
-
}
|
|
97214
|
-
function createHostContext(options = {}) {
|
|
97215
|
-
const args = options.args ?? [];
|
|
97216
|
-
const plan = currentServicePlan(args, options.runtime);
|
|
97217
|
-
const run = options.runCommand ?? runServiceCommand;
|
|
97218
|
-
const sleep4 = options.sleep ?? defaultSleep;
|
|
97219
|
-
const nowMs = options.nowMs ?? Date.now;
|
|
97220
|
-
const readManifest = options.readManifest ?? defaultReadManifest;
|
|
97221
|
-
const writeManifest = options.writeManifest ?? writeManifestAtomic;
|
|
97222
|
-
const removeManifest = options.removeManifest ?? ((path2) => (0, import_node_fs28.rmSync)(path2, { force: true }));
|
|
97223
|
-
const ensureLogDir = options.ensureLogDir ?? (() => {
|
|
97224
|
-
if (plan.logDirectory) (0, import_node_fs28.mkdirSync)(plan.logDirectory, { recursive: true, mode: 448 });
|
|
97225
|
-
});
|
|
97226
|
-
return {
|
|
97227
|
-
args,
|
|
97228
|
-
plan,
|
|
97229
|
-
run,
|
|
97230
|
-
sleep: sleep4,
|
|
97231
|
-
nowMs,
|
|
97232
|
-
readManifest,
|
|
97233
|
-
writeManifest,
|
|
97234
|
-
removeManifest,
|
|
97235
|
-
ensureLogDir,
|
|
97236
|
-
profile: resolveEndpointProfileFromArgs(args)
|
|
97237
|
-
};
|
|
97238
|
-
}
|
|
97239
|
-
function inspectDaemonService(options = {}) {
|
|
97240
|
-
const { plan, run, nowMs } = createHostContext(options);
|
|
97241
|
-
const result = run(plan.isActiveCommand);
|
|
97242
|
-
const state = parseServiceHostState(plan.platform, result);
|
|
97243
|
-
return {
|
|
97244
|
-
state,
|
|
97245
|
-
platform: plan.platform,
|
|
97246
|
-
detail: result.output || void 0,
|
|
97247
|
-
observedAtMs: nowMs()
|
|
97248
|
-
};
|
|
97249
|
-
}
|
|
97250
|
-
function ensureDaemonServiceDefinition(options = {}) {
|
|
97251
|
-
const ctx = createHostContext(options);
|
|
97252
|
-
const { plan, run, readManifest, writeManifest, ensureLogDir } = ctx;
|
|
97253
|
-
let definitionChanged = false;
|
|
97254
|
-
if (plan.manifestPath && plan.manifest) {
|
|
97255
|
-
ensureLogDir();
|
|
97256
|
-
const existing = readManifest(plan.manifestPath);
|
|
97257
|
-
definitionChanged = existing !== plan.manifest;
|
|
97258
|
-
if (definitionChanged) {
|
|
97259
|
-
writeManifest(plan.manifestPath, plan.manifest);
|
|
97260
|
-
}
|
|
97261
|
-
} else if (plan.platform === "win32") {
|
|
97262
|
-
definitionChanged = true;
|
|
97263
|
-
}
|
|
97264
|
-
const inspection = inspectDaemonService(options);
|
|
97265
|
-
const outcome = resolveEnsureDefinitionOutcome({
|
|
97266
|
-
definitionChanged,
|
|
97267
|
-
hostState: inspection.state
|
|
97268
|
-
});
|
|
97269
|
-
if (outcome.updatePending) {
|
|
97270
|
-
return outcome;
|
|
97271
|
-
}
|
|
97272
|
-
if (inspection.state === "running" || inspection.state === "starting") {
|
|
97273
|
-
return outcome;
|
|
97274
|
-
}
|
|
97275
|
-
const definitionCommands = inspection.state === "stopped" ? plan.reloadDefinitionCommands : plan.loadDefinitionCommands;
|
|
97276
|
-
for (const command of definitionCommands) run(command);
|
|
97277
|
-
return outcome;
|
|
97278
|
-
}
|
|
97279
|
-
function enableDaemonService(options = {}) {
|
|
97280
|
-
const { plan, run } = createHostContext(options);
|
|
97281
|
-
for (const command of plan.enableCommands) run(command);
|
|
97282
|
-
}
|
|
97283
|
-
function startDaemonService(options = {}) {
|
|
97284
|
-
const { plan, run } = createHostContext(options);
|
|
97285
|
-
for (const command of plan.startCommands) run(command);
|
|
97286
|
-
}
|
|
97287
|
-
function uninstallDaemonService(args = [], options = {}) {
|
|
97288
|
-
const ctx = createHostContext({ ...options, args: options.args ?? args });
|
|
97289
|
-
for (const command of ctx.plan.uninstallCommands) ctx.run(command);
|
|
97290
|
-
if (ctx.plan.manifestPath) ctx.removeManifest(ctx.plan.manifestPath);
|
|
97291
|
-
console.info("[alan-agent] Per-user daemon service removed");
|
|
97292
|
-
}
|
|
97293
|
-
function installDaemonService(args = [], runtime, options = {}) {
|
|
97294
|
-
const profile = resolveEndpointProfileFromArgs(args);
|
|
97295
|
-
const configPath = resolveAgentConfigPath({ profile });
|
|
97296
|
-
if (!configExistsAtPath(configPath)) {
|
|
97297
|
-
throw new Error(`No ${profile} runtime is configured. Run alan-agent setup or login first.`);
|
|
97298
|
-
}
|
|
97299
|
-
const headless = options.headless ?? args.includes("--headless");
|
|
97300
|
-
const merged = { ...options, args, runtime, headless };
|
|
97301
|
-
const ctx = createHostContext(merged);
|
|
97302
|
-
if (headless) {
|
|
97303
|
-
if (ctx.plan.platform !== "linux") {
|
|
97304
|
-
throw new Error("--headless is only supported on Linux systemd user services");
|
|
97305
|
-
}
|
|
97306
|
-
assertSystemdUserLingerEnabled(merged);
|
|
97307
|
-
}
|
|
97308
|
-
const ensured = ensureDaemonServiceDefinition(merged);
|
|
97309
|
-
enableDaemonService(merged);
|
|
97310
|
-
const inspection = inspectDaemonService(merged);
|
|
97311
|
-
if (ensured.updatePending) {
|
|
97312
|
-
console.info("[alan-agent] Daemon service definition update pending; leaving running service", {
|
|
97313
|
-
profile,
|
|
97314
|
-
state: inspection.state
|
|
97315
|
-
});
|
|
97316
|
-
return;
|
|
97317
|
-
}
|
|
97318
|
-
if (!shouldStartOnInstall(inspection.state)) {
|
|
97319
|
-
console.info("[alan-agent] Per-user daemon service already present", {
|
|
97320
|
-
profile,
|
|
97321
|
-
state: inspection.state
|
|
97322
|
-
});
|
|
97323
|
-
return;
|
|
97324
|
-
}
|
|
97325
|
-
startDaemonService(merged);
|
|
97326
|
-
console.info("[alan-agent] Per-user daemon service installed", { profile });
|
|
97327
|
-
}
|
|
97328
|
-
function printDaemonServiceStatus(args = []) {
|
|
97329
|
-
const plan = currentServicePlan(args);
|
|
97330
|
-
const result = runServiceCommand({ ...plan.statusCommand, tolerateFailure: true });
|
|
97331
|
-
if (result.status !== 0) {
|
|
97332
|
-
process.stdout.write(`unknown
|
|
97333
|
-
${result.output}
|
|
97334
|
-
`);
|
|
97335
|
-
return;
|
|
97336
|
-
}
|
|
97337
|
-
process.stdout.write(`${result.output}
|
|
97338
|
-
`);
|
|
97339
|
-
}
|
|
97340
|
-
|
|
97341
97357
|
// src/skills/skill-cli.ts
|
|
97342
97358
|
var import_promises6 = require("fs/promises");
|
|
97343
97359
|
var import_node_os19 = require("os");
|
|
@@ -97536,13 +97552,7 @@ async function main() {
|
|
|
97536
97552
|
return;
|
|
97537
97553
|
}
|
|
97538
97554
|
if (command === "install") {
|
|
97539
|
-
|
|
97540
|
-
const configured = readConfig();
|
|
97541
|
-
const configurationMode = resolveInstallConfigurationMode(commandArgs, configured);
|
|
97542
|
-
const setup = configurationMode === "setup" ? await setupDaemon(commandArgs) : null;
|
|
97543
|
-
if (configurationMode === "login") await loginWithDeviceCode(commandArgs);
|
|
97544
|
-
if (!setup?.daemonAlreadyRunning) installDaemonService(commandArgs);
|
|
97545
|
-
runMcpIntegrationCommand(["reconcile", ...commandArgs]);
|
|
97555
|
+
await runInstallCommand(commandArgs);
|
|
97546
97556
|
return;
|
|
97547
97557
|
}
|
|
97548
97558
|
if (command === "login") {
|