@rynx-ai/cli 0.1.11-beta.5 → 0.1.11-beta.51

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.
@@ -0,0 +1,78 @@
1
+ import * as prompts from "@clack/prompts";
2
+ const DOWNLOAD_PERCENT_PATTERN = /下载进度:(\d{1,3})%$/u;
3
+ export function createProgressDisplay() {
4
+ if (!prompts.isTTY(process.stdout) || prompts.isCI()) {
5
+ return {
6
+ start: (message) => console.log(message),
7
+ update: (message) => console.log(message),
8
+ succeed: (message) => console.log(message),
9
+ clear: () => undefined,
10
+ };
11
+ }
12
+ const spinner = prompts.spinner({ output: process.stdout });
13
+ const progress = prompts.progress({
14
+ output: process.stdout,
15
+ max: 100,
16
+ size: 28,
17
+ style: "block",
18
+ });
19
+ let spinnerActive = false;
20
+ let progressActive = false;
21
+ let completedPercent = 0;
22
+ const clear = () => {
23
+ if (progressActive)
24
+ progress.clear();
25
+ if (spinnerActive)
26
+ spinner.clear();
27
+ progressActive = false;
28
+ spinnerActive = false;
29
+ completedPercent = 0;
30
+ };
31
+ const finishDownload = () => {
32
+ if (!progressActive)
33
+ return;
34
+ progress.stop("Chrome for Testing 下载完成");
35
+ progressActive = false;
36
+ completedPercent = 0;
37
+ };
38
+ return {
39
+ start(message) {
40
+ clear();
41
+ spinner.start(message);
42
+ spinnerActive = true;
43
+ },
44
+ update(message) {
45
+ const match = DOWNLOAD_PERCENT_PATTERN.exec(message);
46
+ if (match) {
47
+ const percent = Math.min(100, Number(match[1]));
48
+ if (spinnerActive) {
49
+ spinner.clear();
50
+ spinnerActive = false;
51
+ }
52
+ if (!progressActive) {
53
+ progress.start(message);
54
+ progressActive = true;
55
+ }
56
+ progress.advance(percent - completedPercent, message);
57
+ completedPercent = percent;
58
+ return;
59
+ }
60
+ finishDownload();
61
+ if (spinnerActive)
62
+ spinner.message(message);
63
+ else {
64
+ spinner.start(message);
65
+ spinnerActive = true;
66
+ }
67
+ },
68
+ succeed(message) {
69
+ finishDownload();
70
+ if (spinnerActive)
71
+ spinner.stop(message);
72
+ else
73
+ prompts.log.success(message);
74
+ spinnerActive = false;
75
+ },
76
+ clear,
77
+ };
78
+ }
package/dist/run-cli.js CHANGED
@@ -62,6 +62,10 @@ export async function runCli(argv) {
62
62
  return runBrowserCommand(argv.slice(1));
63
63
  case "cleanup":
64
64
  return runCleanupCommand(argv.slice(1));
65
+ case "autostart": {
66
+ const { runAutostartCommand } = await import("./commands/autostart.js");
67
+ return runAutostartCommand(argv.slice(1));
68
+ }
65
69
  case "setup": {
66
70
  const { runSetupCommand } = await import("./commands/setup.js");
67
71
  return runSetupCommand(argv.slice(1));
@@ -9,5 +9,7 @@ export declare function ensureStandaloneDaemon(): Promise<{
9
9
  origin: string;
10
10
  }>;
11
11
  export declare function stopStandaloneDaemon(): Promise<number>;
12
- export declare function statusStandaloneDaemon(): Promise<number>;
12
+ export declare function statusStandaloneDaemon(options?: {
13
+ json?: boolean;
14
+ }): Promise<number>;
13
15
  export declare function streamStandaloneDaemonLogs(): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
+ import { resolveBundledTmux } from "@rynx-ai/tmux";
3
4
  import { installedVersion } from "./version.js";
4
5
  import { ensureDaemonControlEndpoint, resolveDaemonControlEndpoint, } from "./control-endpoint.js";
5
6
  /** Resolve the canonical Builtin Skill directory shipped by this exact CLI. */
@@ -8,6 +9,7 @@ export function standaloneBuiltinSkillsDirectory(moduleUrl = import.meta.url) {
8
9
  }
9
10
  export async function startStandaloneDaemon(options = {}) {
10
11
  const cliVersion = installedVersion();
12
+ const tmuxBin = resolveBundledTmux();
11
13
  const { startDaemon } = await import("@rynx-ai/daemon/lifecycle");
12
14
  return startDaemon({
13
15
  force: options.restart ?? false,
@@ -16,6 +18,7 @@ export async function startStandaloneDaemon(options = {}) {
16
18
  builtinSkillsDir: standaloneBuiltinSkillsDirectory(),
17
19
  cliVersion,
18
20
  productVersion: cliVersion,
21
+ ...(tmuxBin ? { tmuxBin } : {}),
19
22
  },
20
23
  });
21
24
  }
@@ -44,7 +47,23 @@ export async function stopStandaloneDaemon() {
44
47
  const { stopDaemon } = await import("@rynx-ai/daemon/lifecycle");
45
48
  return stopDaemon();
46
49
  }
47
- export async function statusStandaloneDaemon() {
50
+ export async function statusStandaloneDaemon(options = {}) {
51
+ if (options.json) {
52
+ const endpoint = await resolveDaemonControlEndpoint();
53
+ const status = endpoint
54
+ ? {
55
+ state: "running",
56
+ pid: endpoint.pid,
57
+ distribution: endpoint.distribution ?? "unknown",
58
+ lifecycle: endpoint.daemonLifecycle ?? "unknown",
59
+ version: endpoint.productVersion,
60
+ buildId: endpoint.buildId,
61
+ origin: endpoint.origin,
62
+ }
63
+ : { state: "stopped" };
64
+ console.log(JSON.stringify(status));
65
+ return endpoint ? 0 : 1;
66
+ }
48
67
  const { statusDaemon } = await import("@rynx-ai/daemon/lifecycle");
49
68
  return statusDaemon();
50
69
  }
@@ -0,0 +1,53 @@
1
+ import type { AutostartRenderInput, AutostartState } from "./autostart.js";
2
+ import { renderAutostartEnvironmentFile as renderSystemdEnvironmentFile } from "./autostart-environment.js";
3
+ export { renderSystemdEnvironmentFile };
4
+ export declare const RYNX_SYSTEMD_SERVICE = "rynx.service";
5
+ export declare const RYNX_SYSTEMD_SERVICE_ENV = "RYNX_SYSTEMD_SERVICE";
6
+ export interface LinuxSystemdServiceState {
7
+ loadState: string;
8
+ activeState: string;
9
+ subState: string;
10
+ type: string;
11
+ remainAfterExit: string;
12
+ killMode: string;
13
+ killSignal: string;
14
+ restartKillSignal: string;
15
+ finalKillSignal: string;
16
+ sendSigkill: string;
17
+ workingDirectory: string;
18
+ environment: string;
19
+ execStart: string;
20
+ execStop: string;
21
+ }
22
+ export interface LinuxPm2GodProcess {
23
+ pid: number;
24
+ cgroup: string;
25
+ startIdentity: string;
26
+ }
27
+ export type LinuxPm2GodInspection = {
28
+ kind: "absent";
29
+ } | {
30
+ kind: "service-cgroup";
31
+ processes: LinuxPm2GodProcess[];
32
+ } | {
33
+ kind: "external";
34
+ processes: LinuxPm2GodProcess[];
35
+ };
36
+ export interface LinuxPm2InspectionDeps {
37
+ procEntries?: () => string[];
38
+ readText?: (file: string) => string;
39
+ statUid?: (file: string) => number;
40
+ currentUid?: number;
41
+ }
42
+ export declare function renderSystemdUnit(input: AutostartRenderInput): string;
43
+ export declare function linuxUserSystemdAvailable(): boolean;
44
+ export declare function inspectLinuxAutostart(): AutostartState;
45
+ export declare function enableLinuxAutostart(): void;
46
+ export declare function disableLinuxAutostart(): void;
47
+ /** Refresh an existing autostart unit without changing enablement. */
48
+ export declare function refreshLinuxServiceIfPresent(): boolean;
49
+ export declare function assertLinuxSystemdInvocation(): void;
50
+ export declare function parseLinuxSystemdShow(output: string): LinuxSystemdServiceState;
51
+ export declare function inspectLinuxPm2GodProcesses(home: string, deps?: LinuxPm2InspectionDeps): LinuxPm2GodInspection;
52
+ export declare function scanLinuxPm2GodPids(home: string, deps?: LinuxPm2InspectionDeps): number[];
53
+ export declare function linuxSystemdCgroupForPid(pid: number, readText?: (file: string) => string): string;