@femtomc/mu-server 26.2.69 → 26.2.71
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 +7 -3
- package/dist/api/activities.d.ts +2 -0
- package/dist/api/activities.js +160 -0
- package/dist/api/config.d.ts +2 -0
- package/dist/api/config.js +45 -0
- package/dist/api/control_plane.d.ts +2 -0
- package/dist/api/control_plane.js +28 -0
- package/dist/api/cron.d.ts +2 -0
- package/dist/api/cron.js +182 -0
- package/dist/api/events.js +77 -19
- package/dist/api/forum.js +52 -18
- package/dist/api/heartbeats.d.ts +2 -0
- package/dist/api/heartbeats.js +211 -0
- package/dist/api/identities.d.ts +2 -0
- package/dist/api/identities.js +103 -0
- package/dist/api/issues.js +120 -33
- package/dist/api/runs.d.ts +2 -0
- package/dist/api/runs.js +207 -0
- package/dist/cli.js +58 -3
- package/dist/config.d.ts +4 -21
- package/dist/config.js +24 -75
- package/dist/control_plane.d.ts +7 -114
- package/dist/control_plane.js +238 -654
- package/dist/control_plane_bootstrap_helpers.d.ts +16 -0
- package/dist/control_plane_bootstrap_helpers.js +85 -0
- package/dist/control_plane_contract.d.ts +176 -0
- package/dist/control_plane_contract.js +1 -0
- package/dist/control_plane_reload.d.ts +63 -0
- package/dist/control_plane_reload.js +525 -0
- package/dist/control_plane_run_outbox.d.ts +7 -0
- package/dist/control_plane_run_outbox.js +52 -0
- package/dist/control_plane_run_queue_coordinator.d.ts +48 -0
- package/dist/control_plane_run_queue_coordinator.js +327 -0
- package/dist/control_plane_telegram_generation.d.ts +27 -0
- package/dist/control_plane_telegram_generation.js +520 -0
- package/dist/control_plane_wake_delivery.d.ts +50 -0
- package/dist/control_plane_wake_delivery.js +123 -0
- package/dist/cron_request.d.ts +8 -0
- package/dist/cron_request.js +65 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +4 -1
- package/dist/run_queue.d.ts +95 -0
- package/dist/run_queue.js +817 -0
- package/dist/run_supervisor.d.ts +20 -0
- package/dist/run_supervisor.js +25 -1
- package/dist/server.d.ts +12 -49
- package/dist/server.js +365 -2128
- package/dist/server_program_orchestration.d.ts +38 -0
- package/dist/server_program_orchestration.js +254 -0
- package/dist/server_routing.d.ts +31 -0
- package/dist/server_routing.js +230 -0
- package/dist/server_runtime.d.ts +30 -0
- package/dist/server_runtime.js +43 -0
- package/dist/server_types.d.ts +3 -0
- package/dist/server_types.js +16 -0
- package/dist/session_lifecycle.d.ts +11 -0
- package/dist/session_lifecycle.js +149 -0
- package/package.json +7 -6
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
function shellQuoteArg(value) {
|
|
2
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
3
|
+
}
|
|
4
|
+
function shellJoin(args) {
|
|
5
|
+
return args.map(shellQuoteArg).join(" ");
|
|
6
|
+
}
|
|
7
|
+
function createShellCommandRunner(repoRoot) {
|
|
8
|
+
return async (command) => {
|
|
9
|
+
const proc = Bun.spawn({
|
|
10
|
+
cmd: ["bash", "-lc", command],
|
|
11
|
+
cwd: repoRoot,
|
|
12
|
+
env: Bun.env,
|
|
13
|
+
stdin: "ignore",
|
|
14
|
+
stdout: "pipe",
|
|
15
|
+
stderr: "pipe",
|
|
16
|
+
});
|
|
17
|
+
const [exitCode, stdout, stderr] = await Promise.all([
|
|
18
|
+
proc.exited,
|
|
19
|
+
proc.stdout ? new Response(proc.stdout).text() : Promise.resolve(""),
|
|
20
|
+
proc.stderr ? new Response(proc.stderr).text() : Promise.resolve(""),
|
|
21
|
+
]);
|
|
22
|
+
return {
|
|
23
|
+
exitCode: Number.isFinite(exitCode) ? Number(exitCode) : 1,
|
|
24
|
+
stdout,
|
|
25
|
+
stderr,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function describeLifecycleError(err) {
|
|
30
|
+
if (err instanceof Error) {
|
|
31
|
+
return err.message;
|
|
32
|
+
}
|
|
33
|
+
return String(err);
|
|
34
|
+
}
|
|
35
|
+
export function createProcessSessionLifecycle(opts) {
|
|
36
|
+
const runShellCommand = opts.runShellCommand ?? createShellCommandRunner(opts.repoRoot);
|
|
37
|
+
let sessionMutationScheduled = null;
|
|
38
|
+
const scheduleReload = async () => {
|
|
39
|
+
if (sessionMutationScheduled) {
|
|
40
|
+
return {
|
|
41
|
+
ok: true,
|
|
42
|
+
action: sessionMutationScheduled.action,
|
|
43
|
+
message: `session ${sessionMutationScheduled.action} already scheduled`,
|
|
44
|
+
details: { scheduled_at_ms: sessionMutationScheduled.at_ms },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const nowMs = Date.now();
|
|
48
|
+
const restartCommand = Bun.env.MU_RESTART_COMMAND?.trim();
|
|
49
|
+
const inferredArgs = process.argv[0] === process.execPath
|
|
50
|
+
? [process.execPath, ...process.argv.slice(1)]
|
|
51
|
+
: [process.execPath, ...process.argv];
|
|
52
|
+
const restartShellCommand = restartCommand && restartCommand.length > 0 ? restartCommand : shellJoin(inferredArgs);
|
|
53
|
+
if (!restartShellCommand.trim()) {
|
|
54
|
+
return {
|
|
55
|
+
ok: false,
|
|
56
|
+
action: "reload",
|
|
57
|
+
message: "unable to determine restart command",
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const exitDelayMs = 1_000;
|
|
61
|
+
const launchDelayMs = exitDelayMs + 300;
|
|
62
|
+
const delayedShellCommand = `sleep ${(launchDelayMs / 1_000).toFixed(2)}; ${restartShellCommand}`;
|
|
63
|
+
let spawnedPid = null;
|
|
64
|
+
try {
|
|
65
|
+
const proc = Bun.spawn({
|
|
66
|
+
cmd: ["bash", "-lc", delayedShellCommand],
|
|
67
|
+
cwd: opts.repoRoot,
|
|
68
|
+
env: Bun.env,
|
|
69
|
+
stdin: "ignore",
|
|
70
|
+
stdout: "inherit",
|
|
71
|
+
stderr: "inherit",
|
|
72
|
+
});
|
|
73
|
+
spawnedPid = proc.pid ?? null;
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
action: "reload",
|
|
79
|
+
message: `failed to spawn replacement process: ${describeLifecycleError(err)}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
sessionMutationScheduled = { action: "reload", at_ms: nowMs };
|
|
83
|
+
setTimeout(() => {
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}, exitDelayMs);
|
|
86
|
+
return {
|
|
87
|
+
ok: true,
|
|
88
|
+
action: "reload",
|
|
89
|
+
message: "reload scheduled; restarting process",
|
|
90
|
+
details: {
|
|
91
|
+
restart_command: restartShellCommand,
|
|
92
|
+
restart_launch_command: delayedShellCommand,
|
|
93
|
+
spawned_pid: spawnedPid,
|
|
94
|
+
exit_delay_ms: exitDelayMs,
|
|
95
|
+
launch_delay_ms: launchDelayMs,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
const scheduleUpdate = async () => {
|
|
100
|
+
if (sessionMutationScheduled) {
|
|
101
|
+
return {
|
|
102
|
+
ok: true,
|
|
103
|
+
action: sessionMutationScheduled.action,
|
|
104
|
+
message: `session ${sessionMutationScheduled.action} already scheduled`,
|
|
105
|
+
details: { scheduled_at_ms: sessionMutationScheduled.at_ms },
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const updateCommand = Bun.env.MU_UPDATE_COMMAND?.trim() || "npm install -g @femtomc/mu@latest";
|
|
109
|
+
const result = await runShellCommand(updateCommand);
|
|
110
|
+
if (result.exitCode !== 0) {
|
|
111
|
+
return {
|
|
112
|
+
ok: false,
|
|
113
|
+
action: "update",
|
|
114
|
+
message: `update command failed (exit ${result.exitCode})`,
|
|
115
|
+
details: {
|
|
116
|
+
update_command: updateCommand,
|
|
117
|
+
stdout: result.stdout.slice(-4_000),
|
|
118
|
+
stderr: result.stderr.slice(-4_000),
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const reloadResult = await scheduleReload();
|
|
123
|
+
if (!reloadResult.ok) {
|
|
124
|
+
return {
|
|
125
|
+
ok: false,
|
|
126
|
+
action: "update",
|
|
127
|
+
message: reloadResult.message,
|
|
128
|
+
details: {
|
|
129
|
+
update_command: updateCommand,
|
|
130
|
+
reload: reloadResult.details ?? null,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
ok: true,
|
|
136
|
+
action: "update",
|
|
137
|
+
message: "update applied; reload scheduled",
|
|
138
|
+
details: {
|
|
139
|
+
update_command: updateCommand,
|
|
140
|
+
reload: reloadResult.details ?? null,
|
|
141
|
+
update_stdout_tail: result.stdout.slice(-1_000),
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
return {
|
|
146
|
+
reload: scheduleReload,
|
|
147
|
+
update: scheduleUpdate,
|
|
148
|
+
};
|
|
149
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@femtomc/mu-server",
|
|
3
|
-
"version": "26.2.
|
|
3
|
+
"version": "26.2.71",
|
|
4
4
|
"description": "HTTP API server for mu status, work items, messaging setup, and web UI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mu",
|
|
@@ -31,10 +31,11 @@
|
|
|
31
31
|
"start": "bun run dist/cli.js"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@femtomc/mu-agent": "
|
|
35
|
-
"@femtomc/mu-control-plane": "
|
|
36
|
-
"@femtomc/mu-core": "
|
|
37
|
-
"@femtomc/mu-forum": "
|
|
38
|
-
"@femtomc/mu-issue": "
|
|
34
|
+
"@femtomc/mu-agent": "workspace:*",
|
|
35
|
+
"@femtomc/mu-control-plane": "workspace:*",
|
|
36
|
+
"@femtomc/mu-core": "workspace:*",
|
|
37
|
+
"@femtomc/mu-forum": "workspace:*",
|
|
38
|
+
"@femtomc/mu-issue": "workspace:*",
|
|
39
|
+
"@femtomc/mu-orchestrator": "workspace:*"
|
|
39
40
|
}
|
|
40
41
|
}
|