@rynx-ai/daemon 0.1.0 → 0.1.10-beta.2

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 (109) hide show
  1. package/dist/app-browser-host-supervisor.d.ts +97 -0
  2. package/dist/app-browser-host-supervisor.js +529 -0
  3. package/dist/browser-artifact-management.d.ts +20 -0
  4. package/dist/browser-artifact-management.js +61 -0
  5. package/dist/browser-cli-args.d.ts +20 -0
  6. package/dist/browser-cli-args.js +100 -0
  7. package/dist/browser-runner-session-context.d.ts +24 -0
  8. package/dist/browser-runner-session-context.js +113 -0
  9. package/dist/cdp-keyboard-input.d.ts +6 -0
  10. package/dist/cdp-keyboard-input.js +209 -0
  11. package/dist/channel-store.d.ts +0 -6
  12. package/dist/channel-store.js +2 -18
  13. package/dist/chrome-for-testing-release-resolver.d.ts +34 -0
  14. package/dist/chrome-for-testing-release-resolver.js +214 -0
  15. package/dist/chrome-for-testing-store.d.ts +85 -0
  16. package/dist/chrome-for-testing-store.js +836 -0
  17. package/dist/chrome-inspection-gateway.d.ts +58 -0
  18. package/dist/chrome-inspection-gateway.js +806 -0
  19. package/dist/chrome-inspection-manager.d.ts +94 -0
  20. package/dist/chrome-inspection-manager.js +573 -0
  21. package/dist/cli.js +478 -30
  22. package/dist/control-client.d.ts +122 -0
  23. package/dist/control-client.js +855 -0
  24. package/dist/control-deps.js +37 -6
  25. package/dist/control-endpoint.d.ts +14 -0
  26. package/dist/control-endpoint.js +124 -0
  27. package/dist/control-link-store.d.ts +16 -0
  28. package/dist/control-link-store.js +53 -0
  29. package/dist/daemon-build-status.d.ts +8 -0
  30. package/dist/daemon-build-status.js +18 -0
  31. package/dist/daemon-owner.d.ts +14 -0
  32. package/dist/daemon-owner.js +104 -0
  33. package/dist/daemon-server.d.ts +29 -2
  34. package/dist/daemon-server.js +1113 -26
  35. package/dist/db.js +196 -10
  36. package/dist/desktop-browser-host-client.d.ts +35 -0
  37. package/dist/desktop-browser-host-client.js +415 -0
  38. package/dist/direct-runtime-authenticator.d.ts +13 -0
  39. package/dist/direct-runtime-authenticator.js +132 -0
  40. package/dist/direct-runtime-config.d.ts +20 -0
  41. package/dist/direct-runtime-config.js +101 -0
  42. package/dist/embedded-browser-profile-cleanup.d.ts +58 -0
  43. package/dist/embedded-browser-profile-cleanup.js +338 -0
  44. package/dist/headless-browser-host.d.ts +14 -0
  45. package/dist/headless-browser-host.js +2173 -0
  46. package/dist/index-daemon.js +55 -5
  47. package/dist/installation-id.d.ts +33 -0
  48. package/dist/installation-id.js +692 -0
  49. package/dist/maintenance-management.d.ts +11 -0
  50. package/dist/maintenance-management.js +13 -0
  51. package/dist/migrations/cleanup-legacy-sessions.d.ts +0 -3
  52. package/dist/migrations/cleanup-legacy-sessions.js +10 -28
  53. package/dist/plugin-cli.d.ts +30 -0
  54. package/dist/plugin-cli.js +270 -0
  55. package/dist/plugin-host-rpc.d.ts +85 -0
  56. package/dist/plugin-host-rpc.js +878 -0
  57. package/dist/plugin-install-restart.d.ts +13 -0
  58. package/dist/plugin-install-restart.js +24 -0
  59. package/dist/plugin-installer.d.ts +71 -15
  60. package/dist/plugin-installer.js +521 -155
  61. package/dist/plugin-management-service.d.ts +58 -0
  62. package/dist/plugin-management-service.js +240 -0
  63. package/dist/plugin-package.d.ts +61 -0
  64. package/dist/plugin-package.js +732 -0
  65. package/dist/plugin-runtime-control.d.ts +2 -0
  66. package/dist/plugin-runtime-control.js +37 -0
  67. package/dist/plugin-store.d.ts +37 -8
  68. package/dist/plugin-store.js +80 -15
  69. package/dist/plugin-supervisor.d.ts +160 -0
  70. package/dist/plugin-supervisor.js +1143 -0
  71. package/dist/pm2.d.ts +3 -1
  72. package/dist/pm2.js +92 -18
  73. package/dist/provider-cli-service.d.ts +46 -0
  74. package/dist/provider-cli-service.js +510 -0
  75. package/dist/registry.d.ts +6 -19
  76. package/dist/registry.js +22 -87
  77. package/dist/remote-runtime-access-store.d.ts +62 -0
  78. package/dist/remote-runtime-access-store.js +393 -0
  79. package/dist/remote-runtime-admin.d.ts +35 -0
  80. package/dist/remote-runtime-admin.js +110 -0
  81. package/dist/remote-runtime-connection-manager.d.ts +103 -0
  82. package/dist/remote-runtime-connection-manager.js +1575 -0
  83. package/dist/remote-runtime-credential-store.d.ts +45 -0
  84. package/dist/remote-runtime-credential-store.js +639 -0
  85. package/dist/remote-runtime-target-control.d.ts +51 -0
  86. package/dist/remote-runtime-target-control.js +488 -0
  87. package/dist/remote-runtime-target-store.d.ts +56 -0
  88. package/dist/remote-runtime-target-store.js +326 -0
  89. package/dist/runtime-share-addresses.d.ts +21 -0
  90. package/dist/runtime-share-addresses.js +50 -0
  91. package/dist/session-browser-capability-store.d.ts +13 -0
  92. package/dist/session-browser-capability-store.js +58 -0
  93. package/dist/session-emulator-binding-store.d.ts +10 -0
  94. package/dist/session-emulator-binding-store.js +61 -0
  95. package/dist/session-launch-operations.d.ts +41 -0
  96. package/dist/session-launch-operations.js +124 -0
  97. package/dist/session-log-store.js +29 -0
  98. package/dist/session-meta-store.d.ts +3 -2
  99. package/dist/session-meta-store.js +59 -7
  100. package/dist/session-pending-message-store.d.ts +2 -0
  101. package/dist/session-pending-message-store.js +41 -0
  102. package/dist/session-resource-store.d.ts +32 -0
  103. package/dist/session-resource-store.js +700 -0
  104. package/dist/setup.d.ts +16 -0
  105. package/dist/setup.js +144 -5
  106. package/dist/skills-catalog.js +8 -4
  107. package/dist/update.d.ts +11 -2
  108. package/dist/update.js +0 -27
  109. package/package.json +23 -10
package/dist/pm2.d.ts CHANGED
@@ -8,9 +8,11 @@ export declare function formatControlUrl(host: string, port: number): string;
8
8
  * entry from scratch (delete + start) so config flags are always fresh; the
9
9
  * `force === false` path short-circuits when it's already online.
10
10
  */
11
- export declare function startDaemon({ force }: {
11
+ export declare function startDaemon({ force, quiet }: {
12
12
  force: boolean;
13
+ quiet?: boolean;
13
14
  }): number;
15
+ export declare function isPm2DaemonOnline(): boolean;
14
16
  /** Stop and remove the daemon from pm2's process list. */
15
17
  export declare function stopDaemon(): number;
16
18
  /** Print a one-line status; exit 0 only when online. */
package/dist/pm2.js CHANGED
@@ -8,15 +8,18 @@
8
8
  * shipped `ecosystem.cjs` to keep in sync.
9
9
  */
10
10
  import { spawn, spawnSync } from "node:child_process";
11
- import { mkdirSync } from "node:fs";
11
+ import { mkdirSync, realpathSync } from "node:fs";
12
12
  import { createRequire } from "node:module";
13
13
  import { homedir } from "node:os";
14
- import { dirname, join } from "node:path";
14
+ import { dirname, join, resolve } from "node:path";
15
15
  import { fileURLToPath } from "node:url";
16
16
  import { loadConfig } from "@rynx-ai/core";
17
+ import { daemonEntryRestartRequired } from "./daemon-build-status.js";
17
18
  const require = createRequire(import.meta.url);
18
19
  /** pm2 app name — single resident daemon per machine. */
19
20
  const APP_NAME = "rynx";
21
+ const PM2_COMMAND_TIMEOUT_MS = 5_000;
22
+ const DAEMON_PACKAGE_VERSION = require("../package.json").version;
20
23
  /**
21
24
  * Build a dialable control-console URL from the daemon's bind host/port. Bind-all
22
25
  * addresses (`0.0.0.0`, `::`) aren't dialable, so show a loopback host instead.
@@ -57,17 +60,37 @@ function logsDir() {
57
60
  mkdirSync(dir, { recursive: true });
58
61
  return dir;
59
62
  }
63
+ function nodeRuntimeEnv() {
64
+ if (!process.versions.electron) {
65
+ return process.env;
66
+ }
67
+ return { ...process.env, ELECTRON_RUN_AS_NODE: "1" };
68
+ }
60
69
  /** Run a pm2 command inheriting stdio; returns its exit code. */
61
- function runPm2(args) {
70
+ function runPm2(args, quiet = false) {
62
71
  const res = spawnSync(process.execPath, [pm2Bin(), ...args], {
63
- stdio: "inherit",
64
- env: process.env,
72
+ stdio: quiet ? "ignore" : "inherit",
73
+ env: nodeRuntimeEnv(),
74
+ timeout: PM2_COMMAND_TIMEOUT_MS,
75
+ killSignal: "SIGTERM",
65
76
  });
77
+ if (res.error) {
78
+ if (!quiet)
79
+ console.error(`pm2 command failed: ${pm2ErrorMessage(res.error)}`);
80
+ return 1;
81
+ }
66
82
  return res.status ?? 1;
67
83
  }
68
84
  /** Read the daemon's current pm2 record, or null if not registered. */
69
85
  function describe() {
70
- const res = spawnSync(process.execPath, [pm2Bin(), "jlist"], { encoding: "utf8" });
86
+ const res = spawnSync(process.execPath, [pm2Bin(), "jlist"], {
87
+ encoding: "utf8",
88
+ env: nodeRuntimeEnv(),
89
+ timeout: PM2_COMMAND_TIMEOUT_MS,
90
+ killSignal: "SIGTERM",
91
+ });
92
+ if (res.error)
93
+ throw new Error(`pm2 query failed: ${pm2ErrorMessage(res.error)}`);
71
94
  if (res.status !== 0 || !res.stdout)
72
95
  return null;
73
96
  let list;
@@ -79,21 +102,44 @@ function describe() {
79
102
  }
80
103
  return list.find((proc) => proc.name === APP_NAME) ?? null;
81
104
  }
105
+ function pm2ErrorMessage(error) {
106
+ return error.code === "ETIMEDOUT"
107
+ ? `timed out after ${PM2_COMMAND_TIMEOUT_MS}ms`
108
+ : error.message;
109
+ }
82
110
  /**
83
111
  * Start (or, with `force`, reload) the resident daemon. We recreate the pm2
84
112
  * entry from scratch (delete + start) so config flags are always fresh; the
85
113
  * `force === false` path short-circuits when it's already online.
86
114
  */
87
- export function startDaemon({ force }) {
88
- const existing = describe();
89
- if (!force && existing?.pm2_env?.status === "online") {
90
- console.log(`rynx is already running (pid ${existing.pid ?? "?"}). Use \`rynx restart\` to reload.`);
91
- console.log(`Control console: ${styleUrl(controlConsoleUrl())}`);
115
+ export function startDaemon({ force, quiet = false }) {
116
+ let existing;
117
+ try {
118
+ existing = describe();
119
+ }
120
+ catch (error) {
121
+ if (!quiet)
122
+ console.error(error instanceof Error ? error.message : String(error));
123
+ return 1;
124
+ }
125
+ const staleBuild = existing?.pm2_env?.status === "online" &&
126
+ residentBuildRestartRequired(existing);
127
+ if (!force && existing?.pm2_env?.status === "online" && !staleBuild) {
128
+ if (!quiet) {
129
+ console.log(`rynx is already running (pid ${existing.pid ?? "?"}). Use \`rynx restart\` to reload.`);
130
+ console.log(`Control console: ${styleUrl(controlConsoleUrl())}`);
131
+ }
92
132
  return 0;
93
133
  }
134
+ if (staleBuild && !quiet) {
135
+ console.log("A newer daemon build is present on disk; restarting Rynx.");
136
+ }
94
137
  const dir = logsDir();
95
- if (existing)
96
- runPm2(["delete", APP_NAME]);
138
+ if (existing) {
139
+ const removed = runPm2(["delete", APP_NAME], quiet);
140
+ if (removed !== 0)
141
+ return removed;
142
+ }
97
143
  const status = runPm2([
98
144
  "start",
99
145
  daemonEntryPath(),
@@ -112,13 +158,16 @@ export function startDaemon({ force }) {
112
158
  join(dir, "err.log"),
113
159
  "--merge-logs",
114
160
  "--time",
115
- ]);
116
- if (status === 0) {
161
+ ], quiet);
162
+ if (status === 0 && !quiet) {
117
163
  console.log(`rynx ${force ? "restarted" : "started"} (pm2 app "${APP_NAME}", logs: ${dir}).`);
118
164
  console.log(`Control console: ${styleUrl(controlConsoleUrl())}`);
119
165
  }
120
166
  return status;
121
167
  }
168
+ export function isPm2DaemonOnline() {
169
+ return describe()?.pm2_env?.status === "online";
170
+ }
122
171
  /** Stop and remove the daemon from pm2's process list. */
123
172
  export function stopDaemon() {
124
173
  if (!describe()) {
@@ -140,14 +189,39 @@ export function statusDaemon() {
140
189
  const state = app.pm2_env?.status ?? "unknown";
141
190
  const pid = app.pid ? ` pid=${app.pid}` : "";
142
191
  const restarts = app.pm2_env?.restart_time != null ? ` restarts=${app.pm2_env.restart_time}` : "";
143
- console.log(`rynx: ${state}${pid}${restarts}`);
144
- return state === "online" ? 0 : 1;
192
+ const staleBuild = state === "online" && residentBuildRestartRequired(app);
193
+ console.log(`rynx: ${state}${pid}${restarts}` +
194
+ (staleBuild ? " restart-required (run `rynx restart`)" : ""));
195
+ return state === "online" && !staleBuild ? 0 : 1;
145
196
  }
146
197
  /** Stream the daemon's pm2 logs until the user detaches (Ctrl-C). */
147
198
  export function streamLogs() {
148
199
  const child = spawn(process.execPath, [pm2Bin(), "logs", APP_NAME, "--lines", "50"], {
149
200
  stdio: "inherit",
150
- env: process.env,
201
+ env: nodeRuntimeEnv(),
151
202
  });
152
203
  child.on("exit", (code) => process.exit(code ?? 0));
153
204
  }
205
+ function residentBuildRestartRequired(app) {
206
+ const runningEntry = app.pm2_env?.pm_exec_path;
207
+ if (runningEntry && !sameEntryPath(runningEntry, daemonEntryPath()))
208
+ return true;
209
+ const runningVersion = app.pm2_env?.version;
210
+ if (runningVersion &&
211
+ typeof DAEMON_PACKAGE_VERSION === "string" &&
212
+ runningVersion !== DAEMON_PACKAGE_VERSION) {
213
+ return true;
214
+ }
215
+ const startedAt = app.pm2_env?.pm_uptime;
216
+ return typeof startedAt === "number" &&
217
+ Number.isFinite(startedAt) &&
218
+ daemonEntryRestartRequired(daemonEntryPath(), startedAt);
219
+ }
220
+ function sameEntryPath(left, right) {
221
+ try {
222
+ return realpathSync(left) === realpathSync(right);
223
+ }
224
+ catch {
225
+ return resolve(left) === resolve(right);
226
+ }
227
+ }
@@ -0,0 +1,46 @@
1
+ import type { ProviderCliId, ProviderCliJob, ProviderCliOperation, ProviderCliStatusList } from "@rynx-ai/protocol/control";
2
+ interface CommandResult {
3
+ exitCode: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ }
7
+ interface ProviderCliServiceDeps {
8
+ env?: NodeJS.ProcessEnv;
9
+ platform?: NodeJS.Platform;
10
+ now?: () => Date;
11
+ run?: (executable: string, args: string[], options: {
12
+ timeoutMs: number;
13
+ env: NodeJS.ProcessEnv;
14
+ }) => Promise<CommandResult>;
15
+ resolveExecutable?: (binary: string, env: NodeJS.ProcessEnv, platform: NodeJS.Platform) => Promise<string | null>;
16
+ download?: (url: string, maximumBytes: number) => Promise<Uint8Array>;
17
+ }
18
+ export declare class ProviderCliService {
19
+ private readonly env;
20
+ private readonly platform;
21
+ private readonly now;
22
+ private readonly runCommand;
23
+ private readonly resolveCommand;
24
+ private readonly download;
25
+ private readonly latestCache;
26
+ private readonly jobs;
27
+ private readonly activeJobs;
28
+ constructor(deps?: ProviderCliServiceDeps);
29
+ listStatuses(): Promise<ProviderCliStatusList>;
30
+ startOperation(provider: ProviderCliId, operation: ProviderCliOperation): Promise<ProviderCliJob>;
31
+ getJob(id: string): ProviderCliJob | undefined;
32
+ private inspect;
33
+ private resolveProviderExecutable;
34
+ private authStatus;
35
+ private latestVersion;
36
+ private execute;
37
+ private install;
38
+ private update;
39
+ private installTraex;
40
+ private pruneJobs;
41
+ }
42
+ export declare class ProviderCliOperationError extends Error {
43
+ readonly code: "failed_precondition";
44
+ constructor(code: "failed_precondition", message: string);
45
+ }
46
+ export {};