jishushell 0.0.1 → 0.4.2-beta2

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.
Files changed (139) hide show
  1. package/INSTALL-NOTICE +41 -0
  2. package/LICENSE +202 -0
  3. package/README.md +36 -0
  4. package/THIRD-PARTY-NOTICES +387 -0
  5. package/dist/auth.d.ts +6 -0
  6. package/dist/auth.js +88 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.js +290 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.d.ts +24 -0
  12. package/dist/config.js +226 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/constants.d.ts +3 -0
  15. package/dist/constants.js +15 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/control.d.ts +44 -0
  18. package/dist/control.js +1359 -0
  19. package/dist/control.js.map +1 -0
  20. package/dist/crypto-shim.d.ts +1 -0
  21. package/dist/crypto-shim.js +2 -0
  22. package/dist/crypto-shim.js.map +1 -0
  23. package/dist/doctor.d.ts +46 -0
  24. package/dist/doctor.js +937 -0
  25. package/dist/doctor.js.map +1 -0
  26. package/dist/install.d.ts +27 -0
  27. package/dist/install.js +570 -0
  28. package/dist/install.js.map +1 -0
  29. package/dist/routes/auth.d.ts +4 -0
  30. package/dist/routes/auth.js +151 -0
  31. package/dist/routes/auth.js.map +1 -0
  32. package/dist/routes/instances.d.ts +2 -0
  33. package/dist/routes/instances.js +1303 -0
  34. package/dist/routes/instances.js.map +1 -0
  35. package/dist/routes/setup.d.ts +2 -0
  36. package/dist/routes/setup.js +139 -0
  37. package/dist/routes/setup.js.map +1 -0
  38. package/dist/routes/system.d.ts +2 -0
  39. package/dist/routes/system.js +102 -0
  40. package/dist/routes/system.js.map +1 -0
  41. package/dist/server.d.ts +6 -0
  42. package/dist/server.js +392 -0
  43. package/dist/server.js.map +1 -0
  44. package/dist/services/instance-manager.d.ts +67 -0
  45. package/dist/services/instance-manager.js +1319 -0
  46. package/dist/services/instance-manager.js.map +1 -0
  47. package/dist/services/llm-proxy/adapters.d.ts +3 -0
  48. package/dist/services/llm-proxy/adapters.js +309 -0
  49. package/dist/services/llm-proxy/adapters.js.map +1 -0
  50. package/dist/services/llm-proxy/circuit-breaker.d.ts +9 -0
  51. package/dist/services/llm-proxy/circuit-breaker.js +73 -0
  52. package/dist/services/llm-proxy/circuit-breaker.js.map +1 -0
  53. package/dist/services/llm-proxy/encryption.d.ts +6 -0
  54. package/dist/services/llm-proxy/encryption.js +61 -0
  55. package/dist/services/llm-proxy/encryption.js.map +1 -0
  56. package/dist/services/llm-proxy/index.d.ts +24 -0
  57. package/dist/services/llm-proxy/index.js +708 -0
  58. package/dist/services/llm-proxy/index.js.map +1 -0
  59. package/dist/services/llm-proxy/rate-limiter.d.ts +1 -0
  60. package/dist/services/llm-proxy/rate-limiter.js +39 -0
  61. package/dist/services/llm-proxy/rate-limiter.js.map +1 -0
  62. package/dist/services/llm-proxy/sse.d.ts +10 -0
  63. package/dist/services/llm-proxy/sse.js +378 -0
  64. package/dist/services/llm-proxy/sse.js.map +1 -0
  65. package/dist/services/llm-proxy/ssrf.d.ts +16 -0
  66. package/dist/services/llm-proxy/ssrf.js +185 -0
  67. package/dist/services/llm-proxy/ssrf.js.map +1 -0
  68. package/dist/services/llm-proxy/types.d.ts +52 -0
  69. package/dist/services/llm-proxy/types.js +2 -0
  70. package/dist/services/llm-proxy/types.js.map +1 -0
  71. package/dist/services/llm-proxy/usage.d.ts +12 -0
  72. package/dist/services/llm-proxy/usage.js +108 -0
  73. package/dist/services/llm-proxy/usage.js.map +1 -0
  74. package/dist/services/nomad-manager.d.ts +22 -0
  75. package/dist/services/nomad-manager.js +828 -0
  76. package/dist/services/nomad-manager.js.map +1 -0
  77. package/dist/services/plugin-installer.d.ts +22 -0
  78. package/dist/services/plugin-installer.js +102 -0
  79. package/dist/services/plugin-installer.js.map +1 -0
  80. package/dist/services/process-manager.d.ts +25 -0
  81. package/dist/services/process-manager.js +531 -0
  82. package/dist/services/process-manager.js.map +1 -0
  83. package/dist/services/setup-manager.d.ts +93 -0
  84. package/dist/services/setup-manager.js +1922 -0
  85. package/dist/services/setup-manager.js.map +1 -0
  86. package/dist/services/system-monitor.d.ts +1 -0
  87. package/dist/services/system-monitor.js +79 -0
  88. package/dist/services/system-monitor.js.map +1 -0
  89. package/dist/services/telemetry/activation.d.ts +12 -0
  90. package/dist/services/telemetry/activation.js +78 -0
  91. package/dist/services/telemetry/activation.js.map +1 -0
  92. package/dist/services/telemetry/client.d.ts +21 -0
  93. package/dist/services/telemetry/client.js +36 -0
  94. package/dist/services/telemetry/client.js.map +1 -0
  95. package/dist/services/telemetry/device-fingerprint.d.ts +18 -0
  96. package/dist/services/telemetry/device-fingerprint.js +123 -0
  97. package/dist/services/telemetry/device-fingerprint.js.map +1 -0
  98. package/dist/services/telemetry/heartbeat.d.ts +13 -0
  99. package/dist/services/telemetry/heartbeat.js +87 -0
  100. package/dist/services/telemetry/heartbeat.js.map +1 -0
  101. package/dist/services/telemetry/index.d.ts +3 -0
  102. package/dist/services/telemetry/index.js +4 -0
  103. package/dist/services/telemetry/index.js.map +1 -0
  104. package/dist/types.d.ts +51 -0
  105. package/dist/types.js +2 -0
  106. package/dist/types.js.map +1 -0
  107. package/dist/utils/safe-json.d.ts +2 -0
  108. package/dist/utils/safe-json.js +80 -0
  109. package/dist/utils/safe-json.js.map +1 -0
  110. package/dist/utils/ttl-cache.d.ts +29 -0
  111. package/dist/utils/ttl-cache.js +77 -0
  112. package/dist/utils/ttl-cache.js.map +1 -0
  113. package/install/jishu-install.sh +2920 -0
  114. package/install/jishu-uninstall.sh +811 -0
  115. package/install/post-install.sh +124 -0
  116. package/install/post-uninstall.sh +46 -0
  117. package/package.json +57 -8
  118. package/public/assets/Dashboard-Dxsq690N.js +1 -0
  119. package/public/assets/InitPassword-CslWYy8G.js +1 -0
  120. package/public/assets/InstanceDetail-DmEkMj-t.js +14 -0
  121. package/public/assets/Login-d45wtgVA.js +1 -0
  122. package/public/assets/NewInstance-Czp5-AJe.js +1 -0
  123. package/public/assets/Settings-BKMGck05.js +1 -0
  124. package/public/assets/Setup-D3rfLWjZ.js +1 -0
  125. package/public/assets/index-77Ug7feY.css +1 -0
  126. package/public/assets/index-DkDnIohs.js +16 -0
  127. package/public/assets/logo-black-theme-DywLAtFy.png +0 -0
  128. package/public/assets/logo-white-theme-DXffFAWw.png +0 -0
  129. package/public/assets/providers-lBSOjUWy.js +1 -0
  130. package/public/assets/usePolling-CqQ8hrNc.js +1 -0
  131. package/public/assets/vendor-i18n-Bvxxh8Di.js +9 -0
  132. package/public/assets/vendor-react-DONn7uBV.js +59 -0
  133. package/public/index.html +15 -0
  134. package/scripts/build-image.sh +55 -0
  135. package/scripts/run.sh +310 -0
  136. package/scripts/setup-pi.sh +80 -0
  137. package/scripts/start-feishu1.js +46 -0
  138. package/index.js +0 -0
  139. package/jishushell-0.0.1.tgz +0 -0
@@ -0,0 +1,531 @@
1
+ import { execFile as execFileCb, spawn } from "child_process";
2
+ import { promisify } from "util";
3
+ import { existsSync, readFileSync, mkdirSync, readdirSync, statSync, renameSync, openSync, closeSync, readSync } from "fs";
4
+ import { readdir, readFile, writeFile, unlink } from "fs/promises";
5
+ import os from "os";
6
+ import { join } from "path";
7
+ import { getOpenclawHome, getOpenclawConfigPath, getInstanceRuntime, getRuntimeEnv, getGatewayPort, findInstancesSharingOpenclawHome, findInstancesSharingGatewayPort, resolveServiceUser, } from "./instance-manager.js";
8
+ const execFileAsync = promisify(execFileCb);
9
+ // Use OS-reported page size instead of hardcoding 4096 (ARM/RPi may use 16KB pages)
10
+ const PAGE_SIZE = os.pageSize || 4096;
11
+ const IS_DARWIN = process.platform === "darwin";
12
+ const STOPPED = {
13
+ status: "stopped",
14
+ pid: null,
15
+ uptime: null,
16
+ memory_mb: null,
17
+ cpu_percent: null,
18
+ };
19
+ // ---- Pidfile helpers ----
20
+ function getPidfilePath(instanceId) {
21
+ return join(getOpenclawHome(instanceId), "logs", "openclaw.pid");
22
+ }
23
+ /** Read PID from pidfile and verify it's still an openclaw process. */
24
+ async function findProcessFromPidfile(instanceId) {
25
+ const pidfile = getPidfilePath(instanceId);
26
+ try {
27
+ const content = await readFile(pidfile, "utf-8");
28
+ const pid = parseInt(content.trim(), 10);
29
+ if (isNaN(pid) || pid <= 1)
30
+ return null;
31
+ // Verify the PID is still alive
32
+ try {
33
+ process.kill(pid, 0);
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ // Verify it's actually an openclaw process
39
+ if (IS_DARWIN) {
40
+ try {
41
+ const { stdout } = await execFileAsync("ps", ["-p", String(pid), "-o", "command="]);
42
+ if (stdout.includes("openclaw"))
43
+ return pid;
44
+ }
45
+ catch { /* process gone */ }
46
+ }
47
+ else {
48
+ try {
49
+ const cmdline = await readFile(`/proc/${pid}/cmdline`, "utf-8");
50
+ if (cmdline.includes("openclaw"))
51
+ return pid;
52
+ }
53
+ catch { /* process gone */ }
54
+ }
55
+ }
56
+ catch { /* no pidfile or unreadable */ }
57
+ return null;
58
+ }
59
+ async function writePidfile(instanceId, pid) {
60
+ const pidfile = getPidfilePath(instanceId);
61
+ const logDir = join(getOpenclawHome(instanceId), "logs");
62
+ mkdirSync(logDir, { recursive: true });
63
+ await writeFile(pidfile, String(pid), "utf-8");
64
+ }
65
+ async function removePidfile(instanceId) {
66
+ try {
67
+ await unlink(getPidfilePath(instanceId));
68
+ }
69
+ catch { /* ignore */ }
70
+ }
71
+ const _cpuSamples = new Map();
72
+ export function computeCpuPercent(pid, procTicks, totalTicks) {
73
+ const now = Date.now();
74
+ const prev = _cpuSamples.get(pid);
75
+ _cpuSamples.set(pid, { procTicks, totalTicks, ts: now });
76
+ if (!prev || now - prev.ts > 120_000)
77
+ return 0; // first sample or stale (>2min)
78
+ const dProc = procTicks - prev.procTicks;
79
+ const dTotal = totalTicks - prev.totalTicks;
80
+ if (dTotal <= 0)
81
+ return 0;
82
+ return Math.round((dProc / dTotal) * 100 * 10) / 10;
83
+ }
84
+ // Clean up stale samples every 5 minutes
85
+ setInterval(() => {
86
+ const cutoff = Date.now() - 300_000;
87
+ for (const [pid, s] of _cpuSamples) {
88
+ if (s.ts < cutoff)
89
+ _cpuSamples.delete(pid);
90
+ }
91
+ }, 300_000).unref();
92
+ // ---- Platform-specific findProcess ----
93
+ /**
94
+ * Linux: Scan /proc directly using async I/O to avoid blocking the event loop.
95
+ */
96
+ async function findProcessLinux(instanceId, openclawHome, includeNomadManaged) {
97
+ let entries;
98
+ try {
99
+ entries = await readdir("/proc");
100
+ }
101
+ catch {
102
+ return null;
103
+ }
104
+ for (const entry of entries) {
105
+ const pid = parseInt(entry, 10);
106
+ if (isNaN(pid) || pid <= 1)
107
+ continue;
108
+ try {
109
+ // Quick filter by cmdline first (cheap) before reading environ (expensive)
110
+ const cmdline = await readFile(`/proc/${entry}/cmdline`, "utf-8");
111
+ if (!cmdline.includes("openclaw"))
112
+ continue;
113
+ // Only read environ for processes that pass the cmdline filter
114
+ const envContent = await readFile(`/proc/${entry}/environ`, "utf-8");
115
+ const envMap = {};
116
+ for (const e of envContent.split("\0")) {
117
+ const eqIdx = e.indexOf("=");
118
+ if (eqIdx > 0)
119
+ envMap[e.slice(0, eqIdx)] = e.slice(eqIdx + 1);
120
+ }
121
+ if (!includeNomadManaged && (envMap.NOMAD_ALLOC_ID || envMap.NOMAD_JOB_ID)) {
122
+ continue;
123
+ }
124
+ if (envMap.OPENCLAW_INSTANCE_ID === instanceId)
125
+ return pid;
126
+ if (envMap.OPENCLAW_HOME === openclawHome)
127
+ return pid;
128
+ }
129
+ catch {
130
+ // Can't read /proc/pid — permission denied or process exited
131
+ }
132
+ }
133
+ return null;
134
+ }
135
+ /**
136
+ * macOS: Use `ps aux` to find openclaw processes, then check environment
137
+ * via `ps -p PID -e` to match OPENCLAW_INSTANCE_ID or OPENCLAW_HOME.
138
+ */
139
+ async function findProcessDarwin(instanceId, openclawHome, includeNomadManaged) {
140
+ try {
141
+ const { stdout } = await execFileAsync("ps", ["aux"]);
142
+ const lines = stdout.split("\n");
143
+ for (const line of lines) {
144
+ if (!line.includes("openclaw"))
145
+ continue;
146
+ const parts = line.trim().split(/\s+/);
147
+ const pid = parseInt(parts[1], 10);
148
+ if (isNaN(pid) || pid <= 1)
149
+ continue;
150
+ // Get full environment of the process to match instance
151
+ try {
152
+ const { stdout: envOut } = await execFileAsync("ps", ["-p", String(pid), "-wwwE", "-o", "command="]);
153
+ if (!includeNomadManaged && (envOut.includes("NOMAD_ALLOC_ID=") || envOut.includes("NOMAD_JOB_ID="))) {
154
+ continue;
155
+ }
156
+ // Parse env vars from ps -E output (space-separated KEY=VALUE after the command)
157
+ if (envOut.includes(`OPENCLAW_INSTANCE_ID=${instanceId}`))
158
+ return pid;
159
+ if (envOut.includes(`OPENCLAW_HOME=${openclawHome}`))
160
+ return pid;
161
+ }
162
+ catch {
163
+ // Process may have exited between ps aux and ps -p
164
+ }
165
+ }
166
+ }
167
+ catch { /* ps command failed */ }
168
+ return null;
169
+ }
170
+ /**
171
+ * Find the PID of an openclaw process for the given instance.
172
+ * Checks pidfile first as a fast path, then falls back to platform-specific scanning.
173
+ */
174
+ async function findProcess(instanceId, includeNomadManaged = true) {
175
+ const openclawHome = getOpenclawHome(instanceId);
176
+ // Fast path: check pidfile first
177
+ const pidFromFile = await findProcessFromPidfile(instanceId);
178
+ if (pidFromFile !== null)
179
+ return pidFromFile;
180
+ // Fall back to platform-specific process scanning
181
+ if (IS_DARWIN) {
182
+ return findProcessDarwin(instanceId, openclawHome, includeNomadManaged);
183
+ }
184
+ return findProcessLinux(instanceId, openclawHome, includeNomadManaged);
185
+ }
186
+ /**
187
+ * Linux: Read /proc asynchronously to avoid blocking the event loop on RPi SD cards.
188
+ */
189
+ async function getProcessStatusLinux(pid) {
190
+ try {
191
+ process.kill(pid, 0);
192
+ const [statContent, uptimeContent, cpuStatContent] = await Promise.all([
193
+ readFile(`/proc/${pid}/stat`, "utf-8"),
194
+ readFile("/proc/uptime", "utf-8"),
195
+ readFile("/proc/stat", "utf-8").catch(() => ""),
196
+ ]);
197
+ const stat = statContent.split(" ");
198
+ const startTimeTicks = parseInt(stat[21], 10);
199
+ const rssPages = parseInt(stat[23], 10);
200
+ // utime (field 13) + stime (field 14) = total process CPU ticks
201
+ const utime = parseInt(stat[13], 10) || 0;
202
+ const stime = parseInt(stat[14], 10) || 0;
203
+ const procTicks = utime + stime;
204
+ const systemUptime = parseFloat(uptimeContent.split(" ")[0]);
205
+ const clockTicks = 100; // standard on Linux
206
+ const processStartSeconds = startTimeTicks / clockTicks;
207
+ const uptime = Math.floor(systemUptime - processStartSeconds);
208
+ const memoryMb = Math.round((rssPages * PAGE_SIZE) / (1024 * 1024) * 10) / 10;
209
+ // Parse total CPU ticks from /proc/stat first line: "cpu <user> <nice> <system> <idle> ..."
210
+ let totalTicks = 0;
211
+ const cpuLine = cpuStatContent.split("\n")[0];
212
+ if (cpuLine?.startsWith("cpu ")) {
213
+ totalTicks = cpuLine.trim().split(/\s+/).slice(1).reduce((sum, n) => sum + (parseInt(n, 10) || 0), 0);
214
+ }
215
+ const cpuPercent = totalTicks > 0 ? computeCpuPercent(pid, procTicks, totalTicks) : 0;
216
+ return {
217
+ status: "running",
218
+ pid,
219
+ uptime: uptime > 0 ? uptime : null,
220
+ memory_mb: memoryMb,
221
+ cpu_percent: cpuPercent,
222
+ };
223
+ }
224
+ catch {
225
+ return { ...STOPPED };
226
+ }
227
+ }
228
+ /**
229
+ * Parse ps etime format [[dd-]hh:]mm:ss into seconds.
230
+ * Examples: "03:22" → 202, "01:03:22" → 3802, "2-01:03:22" → 176602
231
+ */
232
+ export function parseEtime(etime) {
233
+ const trimmed = etime.trim();
234
+ let days = 0;
235
+ let rest = trimmed;
236
+ // Check for days: "dd-hh:mm:ss"
237
+ const dashIdx = rest.indexOf("-");
238
+ if (dashIdx !== -1) {
239
+ days = parseInt(rest.slice(0, dashIdx), 10);
240
+ rest = rest.slice(dashIdx + 1);
241
+ }
242
+ const parts = rest.split(":").map(p => parseInt(p, 10));
243
+ let seconds = 0;
244
+ if (parts.length === 3) {
245
+ seconds = parts[0] * 3600 + parts[1] * 60 + parts[2];
246
+ }
247
+ else if (parts.length === 2) {
248
+ seconds = parts[0] * 60 + parts[1];
249
+ }
250
+ else {
251
+ seconds = parts[0] || 0;
252
+ }
253
+ return days * 86400 + seconds;
254
+ }
255
+ /**
256
+ * macOS: Use `ps -o pid,rss,etime -p PID` to get memory and uptime.
257
+ */
258
+ async function getProcessStatusDarwin(pid) {
259
+ try {
260
+ process.kill(pid, 0);
261
+ const { stdout } = await execFileAsync("ps", ["-o", "pid,rss,etime,%cpu", "-p", String(pid)]);
262
+ const lines = stdout.trim().split("\n");
263
+ // Skip header line
264
+ if (lines.length < 2)
265
+ return { ...STOPPED };
266
+ const parts = lines[1].trim().split(/\s+/);
267
+ // parts: [PID, RSS(KB), ETIME, %CPU]
268
+ if (parts.length < 4)
269
+ return { ...STOPPED };
270
+ const rssKb = parseInt(parts[1], 10);
271
+ const memoryMb = Math.round((rssKb / 1024) * 10) / 10;
272
+ const uptime = parseEtime(parts[2]);
273
+ const cpuPercent = Math.round(parseFloat(parts[3]) * 10) / 10 || 0;
274
+ return {
275
+ status: "running",
276
+ pid,
277
+ uptime: uptime > 0 ? uptime : null,
278
+ memory_mb: memoryMb,
279
+ cpu_percent: cpuPercent,
280
+ };
281
+ }
282
+ catch {
283
+ return { ...STOPPED };
284
+ }
285
+ }
286
+ async function getProcessStatus(pid) {
287
+ if (IS_DARWIN) {
288
+ return getProcessStatusDarwin(pid);
289
+ }
290
+ return getProcessStatusLinux(pid);
291
+ }
292
+ export async function getStatus(instanceId) {
293
+ const pid = await findProcess(instanceId);
294
+ if (pid === null)
295
+ return { ...STOPPED };
296
+ return getProcessStatus(pid);
297
+ }
298
+ export async function getLegacyStatus(instanceId) {
299
+ const pid = await findProcess(instanceId, false);
300
+ if (pid === null)
301
+ return { ...STOPPED };
302
+ return getProcessStatus(pid);
303
+ }
304
+ export async function startInstance(instanceId) {
305
+ if (await findProcess(instanceId) !== null) {
306
+ return { ok: false, error: "Instance is already running" };
307
+ }
308
+ // Check for OPENCLAW_HOME conflicts
309
+ for (const otherId of findInstancesSharingOpenclawHome(instanceId)) {
310
+ if (await findProcess(otherId) !== null) {
311
+ return { ok: false, error: `OPENCLAW_HOME is shared with running instance: ${otherId}` };
312
+ }
313
+ }
314
+ // Check for gateway port conflicts
315
+ const port = getGatewayPort(instanceId);
316
+ for (const otherId of findInstancesSharingGatewayPort(instanceId)) {
317
+ if (await findProcess(otherId) !== null) {
318
+ return { ok: false, error: `Gateway port ${port} is already in use by running instance: ${otherId}` };
319
+ }
320
+ }
321
+ const openclawHome = getOpenclawHome(instanceId);
322
+ const configPath = getOpenclawConfigPath(instanceId);
323
+ if (!existsSync(configPath)) {
324
+ return { ok: false, error: "Config file not found" };
325
+ }
326
+ const runtime = getInstanceRuntime(instanceId);
327
+ const command = runtime.command;
328
+ const args = runtime.args || [];
329
+ if (!command || !existsSync(command)) {
330
+ return { ok: false, error: `OpenClaw 命令不存在: ${command || '未配置'}` };
331
+ }
332
+ const cwd = runtime.cwd || openclawHome;
333
+ // build env — whitelist safe variables only
334
+ const SAFE_ENV_PREFIXES = ["HOME", "USER", "LANG", "LC_", "PATH", "SHELL", "TERM", "TMPDIR", "TZ", "NODE", "NPM_", "XDG_"];
335
+ const env = {};
336
+ for (const [k, v] of Object.entries(process.env)) {
337
+ if (v != null && SAFE_ENV_PREFIXES.some(p => k === p || k.startsWith(p))) {
338
+ env[k] = v;
339
+ }
340
+ }
341
+ Object.assign(env, getRuntimeEnv(instanceId));
342
+ env.OPENCLAW_HOME = openclawHome;
343
+ env.OPENCLAW_INSTANCE_ID = instanceId;
344
+ const logDir = join(openclawHome, "logs");
345
+ mkdirSync(logDir, { recursive: true });
346
+ // Rotate log files if > 10MB
347
+ const MAX_LOG_SIZE = 10 * 1024 * 1024;
348
+ for (const logName of ["stdout.log", "stderr.log"]) {
349
+ const logPath = join(logDir, logName);
350
+ try {
351
+ if (existsSync(logPath) && statSync(logPath).size > MAX_LOG_SIZE) {
352
+ renameSync(logPath, logPath + ".1");
353
+ }
354
+ }
355
+ catch { /* ignore rotation errors */ }
356
+ }
357
+ // Use OS-level file descriptors for logging — survives JishuShell restarts
358
+ const outFd = openSync(join(logDir, "stdout.log"), "a");
359
+ const errFd = openSync(join(logDir, "stderr.log"), "a");
360
+ try {
361
+ // When JishuShell runs as root, drop privileges to the runtime user so the
362
+ // child process can read/write its own files without permission mismatches.
363
+ const svcUser = resolveServiceUser();
364
+ const spawnOpts = {
365
+ cwd,
366
+ env,
367
+ detached: true,
368
+ stdio: ["ignore", outFd, errFd],
369
+ };
370
+ if (svcUser && typeof process.getuid === "function" && process.getuid() === 0) {
371
+ spawnOpts.uid = svcUser.uid;
372
+ spawnOpts.gid = svcUser.gid;
373
+ // Set HOME/USER env to match the target user, not root's env
374
+ env.HOME = os.userInfo({ encoding: "utf-8" }).homedir !== "/root"
375
+ ? os.userInfo({ encoding: "utf-8" }).homedir
376
+ : `/home/${svcUser.username}`;
377
+ env.USER = svcUser.username;
378
+ }
379
+ const child = spawn(command, args.map(String), spawnOpts);
380
+ child.unref();
381
+ // Write pidfile for cross-platform PID tracking
382
+ if (child.pid) {
383
+ await writePidfile(instanceId, child.pid);
384
+ }
385
+ return { ok: true, pid: child.pid };
386
+ }
387
+ catch (e) {
388
+ if (e.code === "ENOENT") {
389
+ return { ok: false, error: `Binary '${command}' not found` };
390
+ }
391
+ return { ok: false, error: e.message };
392
+ }
393
+ finally {
394
+ // Close our copies — child process keeps its own
395
+ closeSync(outFd);
396
+ closeSync(errFd);
397
+ }
398
+ }
399
+ export async function stopInstance(instanceId) {
400
+ const pid = await findProcess(instanceId);
401
+ if (pid === null) {
402
+ return { ok: false, error: "Instance is not running" };
403
+ }
404
+ // Verify PID still belongs to an openclaw process before sending signals
405
+ // to guard against PID reuse (another process got the same PID)
406
+ try {
407
+ if (IS_DARWIN) {
408
+ const { stdout: cmdOut } = await execFileAsync("ps", ["-p", String(pid), "-o", "command="]);
409
+ if (!cmdOut.includes("openclaw")) {
410
+ return { ok: false, error: "Process PID was reused by another program — not killing" };
411
+ }
412
+ }
413
+ else {
414
+ const cmdline = readFileSync(`/proc/${pid}/cmdline`, "utf-8");
415
+ if (!cmdline.includes("openclaw")) {
416
+ return { ok: false, error: "Process PID was reused by another program — not killing" };
417
+ }
418
+ }
419
+ }
420
+ catch {
421
+ await removePidfile(instanceId);
422
+ return { ok: false, error: "Process no longer exists" };
423
+ }
424
+ try {
425
+ // Kill the entire process group (negative pid) to clean up child processes
426
+ try {
427
+ process.kill(-pid, "SIGTERM");
428
+ }
429
+ catch {
430
+ process.kill(pid, "SIGTERM");
431
+ }
432
+ // Wait up to 10s for process to exit
433
+ const deadline = Date.now() + 10000;
434
+ while (Date.now() < deadline) {
435
+ try {
436
+ process.kill(pid, 0);
437
+ await new Promise(r => setTimeout(r, 500));
438
+ }
439
+ catch {
440
+ await removePidfile(instanceId);
441
+ return { ok: true };
442
+ }
443
+ }
444
+ // Force kill process group
445
+ try {
446
+ process.kill(-pid, "SIGKILL");
447
+ }
448
+ catch {
449
+ try {
450
+ process.kill(pid, "SIGKILL");
451
+ }
452
+ catch { /* already dead */ }
453
+ }
454
+ await removePidfile(instanceId);
455
+ return { ok: true, warning: "Force killed after timeout" };
456
+ }
457
+ catch (e) {
458
+ return { ok: false, error: e.message };
459
+ }
460
+ }
461
+ export async function restartInstance(instanceId) {
462
+ await stopInstance(instanceId);
463
+ // Wait 2 seconds
464
+ await new Promise(r => setTimeout(r, 2000));
465
+ return startInstance(instanceId);
466
+ }
467
+ const VALID_LOG_TYPES = new Set(["stdout", "stderr"]);
468
+ export function getLogs(instanceId, lines = 100, logType = "stderr") {
469
+ // Defense-in-depth: only allow known log types to prevent path traversal
470
+ if (!VALID_LOG_TYPES.has(logType))
471
+ logType = "stderr";
472
+ const openclawHome = getOpenclawHome(instanceId);
473
+ let logFile = join(openclawHome, "logs", `${logType}.log`);
474
+ if (!existsSync(logFile))
475
+ logFile = join(openclawHome, `${logType}.log`);
476
+ if (!existsSync(logFile)) {
477
+ // Try most recent log in logs dir
478
+ const logDir = join(openclawHome, "logs");
479
+ if (existsSync(logDir)) {
480
+ const files = readdirSync(logDir)
481
+ .filter((f) => f.endsWith(".log"))
482
+ .map((f) => ({ name: f, mtime: statSync(join(logDir, f)).mtimeMs }))
483
+ .sort((a, b) => b.mtime - a.mtime);
484
+ if (files.length)
485
+ logFile = join(logDir, files[0].name);
486
+ }
487
+ }
488
+ if (!existsSync(logFile))
489
+ return [];
490
+ // Read only the tail of the file to avoid OOM on large logs (RPi has limited RAM)
491
+ const MAX_TAIL_BYTES = 512 * 1024; // 512KB cap
492
+ const fileSize = statSync(logFile).size;
493
+ if (fileSize === 0)
494
+ return [];
495
+ // Only allocate what we actually need, not a fixed 512KB
496
+ const start = Math.max(0, fileSize - MAX_TAIL_BYTES);
497
+ const length = Math.min(fileSize, MAX_TAIL_BYTES);
498
+ const fd = openSync(logFile, "r");
499
+ try {
500
+ const buf = Buffer.allocUnsafe(length); // skip zero-fill — we read into it immediately
501
+ readSync(fd, buf, 0, length, start);
502
+ const text = buf.toString("utf-8");
503
+ const allLines = text.split("\n");
504
+ // If we started mid-file, drop the potentially partial first line
505
+ if (start > 0)
506
+ allLines.shift();
507
+ return allLines.slice(-lines);
508
+ }
509
+ finally {
510
+ closeSync(fd);
511
+ }
512
+ }
513
+ export async function exec(instanceId, command, timeoutMs = 120_000) {
514
+ const openclawHome = getOpenclawHome(instanceId);
515
+ try {
516
+ const { stdout, stderr } = await execFileAsync(command[0], command.slice(1), {
517
+ cwd: openclawHome,
518
+ env: { PATH: process.env.PATH, HOME: process.env.HOME, LANG: process.env.LANG, OPENCLAW_HOME: openclawHome },
519
+ timeout: timeoutMs,
520
+ });
521
+ return { stdout, stderr, exitCode: 0 };
522
+ }
523
+ catch (e) {
524
+ return {
525
+ stdout: e.stdout || "",
526
+ stderr: e.stderr || e.message,
527
+ exitCode: e.code ?? 1,
528
+ };
529
+ }
530
+ }
531
+ //# sourceMappingURL=process-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../src/services/process-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ export declare function setServerPort(port: number): void;
2
+ export interface TaskEvent {
3
+ type: "log" | "progress" | "done" | "error";
4
+ message: string;
5
+ progress?: number;
6
+ }
7
+ interface Task {
8
+ id: string;
9
+ name: string;
10
+ status: "running" | "done" | "error";
11
+ events: TaskEvent[];
12
+ listeners: Set<(event: TaskEvent) => void>;
13
+ }
14
+ export declare function getTask(id: string): Task | undefined;
15
+ export interface TaskSnapshot {
16
+ id: string;
17
+ name: string;
18
+ status: "running" | "done" | "error";
19
+ events: TaskEvent[];
20
+ }
21
+ export declare function getTaskSnapshot(id: string): TaskSnapshot | undefined;
22
+ /** Find running tasks, optionally filtered by name prefix */
23
+ export declare function getRunningTasks(namePrefix?: string): Array<{
24
+ id: string;
25
+ name: string;
26
+ }>;
27
+ export declare function subscribeTask(id: string, listener: (event: TaskEvent) => void): (() => void) | null;
28
+ export interface DependencyStatus {
29
+ name: string;
30
+ installed: boolean;
31
+ running: boolean;
32
+ version: string;
33
+ path: string;
34
+ error?: string;
35
+ needsUpgrade?: boolean;
36
+ }
37
+ export interface SetupStatus {
38
+ node: DependencyStatus;
39
+ docker: DependencyStatus;
40
+ nomad: DependencyStatus;
41
+ openclaw: DependencyStatus;
42
+ ready: boolean;
43
+ providerConfigured: boolean;
44
+ dockerImageReady: boolean;
45
+ hasSudo: boolean;
46
+ /** True when cgroup memory was just enabled and a reboot is needed for Docker memory stats */
47
+ needsReboot?: boolean;
48
+ /** Currently running setup tasks (so frontend can resume polling after refresh) */
49
+ runningTasks?: Array<{
50
+ id: string;
51
+ name: string;
52
+ }>;
53
+ }
54
+ /** Enable cgroup memory in boot cmdline if not already enabled. Returns true if a reboot is needed. */
55
+ export declare function ensureCgroupMemory(): boolean;
56
+ export declare function getSetupStatus(): SetupStatus;
57
+ export interface InstallResult {
58
+ ok: boolean;
59
+ message: string;
60
+ error?: string;
61
+ taskId?: string;
62
+ needsReboot?: boolean;
63
+ }
64
+ export declare function upgradeNode(targetMajor?: number): Promise<InstallResult>;
65
+ export declare function installDocker(): Promise<InstallResult>;
66
+ export declare function startInstallDocker(): InstallResult;
67
+ export declare function installNomad(): Promise<InstallResult>;
68
+ export declare function loadNomadToken(): void;
69
+ export declare function ensureNomadMemoryOversubscriptionEnabled(): Promise<void>;
70
+ export declare function startNomad(): Promise<InstallResult>;
71
+ export declare function stopNomad(): Promise<InstallResult>;
72
+ export declare function installNomadSystemd(): InstallResult;
73
+ export declare function installJishushellSystemd(port?: number): InstallResult;
74
+ export declare function installOpenclaw(version?: string): Promise<InstallResult>;
75
+ export declare const BASE_IMAGE_TAG = "jishushell-base:v1";
76
+ export declare function buildOpenclawDockerImage(tag?: string): Promise<InstallResult>;
77
+ export declare function startBuildOpenclawDockerImage(tag?: string): InstallResult;
78
+ export declare function buildCustomOpenclawImage(tag?: string): Promise<InstallResult>;
79
+ export declare function startBuildCustomOpenclawImage(tag?: string): InstallResult;
80
+ export interface SetupProgress {
81
+ step: string;
82
+ status: "pending" | "running" | "done" | "error";
83
+ message: string;
84
+ }
85
+ export declare function runFullSetup(options?: {
86
+ installNomad?: boolean;
87
+ installOpenclaw?: boolean;
88
+ buildDockerImage?: boolean;
89
+ }): Promise<{
90
+ ok: boolean;
91
+ steps: SetupProgress[];
92
+ }>;
93
+ export {};