macroclaw 0.8.0 → 0.10.0

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/src/service.ts CHANGED
@@ -50,12 +50,22 @@ interface LinuxUser {
50
50
  home: string;
51
51
  }
52
52
 
53
+ export interface ServiceStatus {
54
+ installed: boolean;
55
+ running: boolean;
56
+ platform: Platform;
57
+ pid?: number;
58
+ uptime?: string;
59
+ }
60
+
53
61
  export interface SystemService {
54
62
  install: (oauthToken?: string) => string;
55
63
  uninstall: () => void;
56
64
  start: () => string;
57
65
  stop: () => void;
58
66
  update: () => string;
67
+ status: () => ServiceStatus;
68
+ logs: (follow?: boolean) => string;
59
69
  }
60
70
 
61
71
  export class ServiceManager implements SystemService {
@@ -229,6 +239,46 @@ export class ServiceManager implements SystemService {
229
239
  return this.#logTailCommand();
230
240
  }
231
241
 
242
+ status(): ServiceStatus {
243
+ const result: ServiceStatus = {
244
+ installed: this.isInstalled,
245
+ running: this.isRunning,
246
+ platform: this.#platform,
247
+ };
248
+
249
+ if (result.running) {
250
+ if (this.#platform === "launchd") {
251
+ try {
252
+ const out = this.#deps.execSync(`launchctl list ${LAUNCHD_LABEL}`);
253
+ const pidMatch = /"PID"\s*=\s*(\d+)/.exec(out);
254
+ if (pidMatch) result.pid = Number(pidMatch[1]);
255
+ } catch { /* best effort */ }
256
+ } else {
257
+ try {
258
+ const out = this.#deps.execSync("systemctl show macroclaw --property=MainPID,ActiveEnterTimestamp --no-pager");
259
+ const pidMatch = /MainPID=(\d+)/.exec(out);
260
+ if (pidMatch && pidMatch[1] !== "0") result.pid = Number(pidMatch[1]);
261
+ const tsMatch = /ActiveEnterTimestamp=(.+)/.exec(out);
262
+ if (tsMatch?.[1].trim()) result.uptime = tsMatch[1].trim();
263
+ } catch { /* best effort */ }
264
+ }
265
+ }
266
+
267
+ return result;
268
+ }
269
+
270
+ logs(follow = false): string {
271
+ if (this.#platform === "launchd") {
272
+ const logDir = resolve(this.#deps.home, ".macroclaw/logs");
273
+ return follow
274
+ ? `tail -f ${logDir}/stdout.log ${logDir}/stderr.log`
275
+ : `tail -n 50 ${logDir}/stdout.log`;
276
+ }
277
+ return follow
278
+ ? "journalctl -u macroclaw -f"
279
+ : "journalctl -u macroclaw -n 50 --no-pager";
280
+ }
281
+
232
282
  #resolvePath(binary: string): string {
233
283
  try {
234
284
  return this.#deps.execSync(`which ${binary}`).trim();