@rynx-ai/daemon 0.1.10 → 0.1.11-beta.10
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/bundled-plugins/.rynx-plugin/marketplace.json +10 -0
- package/bundled-plugins/plugins/lark/.rynx-plugin/plugin.json +25 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/mirror-index.d.ts +48 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/mirror-index.js +56 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-mirror.d.ts +85 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-mirror.js +333 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-watcher.d.ts +109 -0
- package/bundled-plugins/plugins/lark/dist/cli-mirror/rollout-watcher.js +347 -0
- package/bundled-plugins/plugins/lark/dist/host-adapters.d.ts +95 -0
- package/bundled-plugins/plugins/lark/dist/host-adapters.js +506 -0
- package/bundled-plugins/plugins/lark/dist/index.d.ts +7 -0
- package/bundled-plugins/plugins/lark/dist/index.js +7 -0
- package/bundled-plugins/plugins/lark/dist/lark-card-stream.d.ts +363 -0
- package/bundled-plugins/plugins/lark/dist/lark-card-stream.js +1335 -0
- package/bundled-plugins/plugins/lark/dist/lark-config-store.d.ts +30 -0
- package/bundled-plugins/plugins/lark/dist/lark-config-store.js +135 -0
- package/bundled-plugins/plugins/lark/dist/lark-content.d.ts +30 -0
- package/bundled-plugins/plugins/lark/dist/lark-content.js +138 -0
- package/bundled-plugins/plugins/lark/dist/lark-conversation-directory.d.ts +65 -0
- package/bundled-plugins/plugins/lark/dist/lark-conversation-directory.js +106 -0
- package/bundled-plugins/plugins/lark/dist/lark-diff-card.d.ts +25 -0
- package/bundled-plugins/plugins/lark/dist/lark-diff-card.js +58 -0
- package/bundled-plugins/plugins/lark/dist/lark-fork-transcript.d.ts +16 -0
- package/bundled-plugins/plugins/lark/dist/lark-fork-transcript.js +141 -0
- package/bundled-plugins/plugins/lark/dist/lark-resume-card.d.ts +31 -0
- package/bundled-plugins/plugins/lark/dist/lark-resume-card.js +105 -0
- package/bundled-plugins/plugins/lark/dist/lark-runtime-state-store.d.ts +18 -0
- package/bundled-plugins/plugins/lark/dist/lark-runtime-state-store.js +95 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/client.d.ts +8 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/client.js +32 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/index.d.ts +1 -0
- package/bundled-plugins/plugins/lark/dist/lark-sdk/index.js +1 -0
- package/bundled-plugins/plugins/lark/dist/lark-sender.d.ts +114 -0
- package/bundled-plugins/plugins/lark/dist/lark-sender.js +323 -0
- package/bundled-plugins/plugins/lark/dist/lark-session-store.d.ts +13 -0
- package/bundled-plugins/plugins/lark/dist/lark-session-store.js +14 -0
- package/bundled-plugins/plugins/lark/dist/lark-settings-card.d.ts +55 -0
- package/bundled-plugins/plugins/lark/dist/lark-settings-card.js +158 -0
- package/bundled-plugins/plugins/lark/dist/lark-setup.d.ts +39 -0
- package/bundled-plugins/plugins/lark/dist/lark-setup.js +103 -0
- package/bundled-plugins/plugins/lark/dist/lark.d.ts +507 -0
- package/bundled-plugins/plugins/lark/dist/lark.js +1975 -0
- package/bundled-plugins/plugins/lark/dist/runtime.d.ts +13 -0
- package/bundled-plugins/plugins/lark/dist/runtime.js +131328 -0
- package/bundled-plugins/plugins/lark/dist/settings.d.ts +7 -0
- package/bundled-plugins/plugins/lark/dist/settings.js +126971 -0
- package/bundled-plugins/plugins/lark/package.json +57 -0
- package/bundled-plugins/plugins/lark/ui/assets/index-CGUVAMsv.css +1 -0
- package/bundled-plugins/plugins/lark/ui/assets/index-D8Amoe6a.js +201 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/bundled-plugins/plugins/lark/ui/index.html +13 -0
- package/dist/agent-file.js +0 -1
- package/dist/browser-artifact-management.d.ts +4 -1
- package/dist/browser-artifact-management.js +18 -10
- package/dist/browser-artifacts.d.ts +1 -0
- package/dist/browser-artifacts.js +1 -0
- package/dist/bundled-plugins.d.ts +15 -0
- package/dist/bundled-plugins.js +134 -0
- package/dist/chrome-for-testing-runtime.d.ts +27 -0
- package/dist/chrome-for-testing-runtime.js +193 -0
- package/dist/chrome-for-testing-store.d.ts +2 -0
- package/dist/chrome-for-testing-store.js +9 -0
- package/dist/control-deps.d.ts +6 -2
- package/dist/control-deps.js +88 -82
- package/dist/daemon-server.d.ts +7 -1
- package/dist/daemon-server.js +310 -87
- package/dist/db.js +181 -124
- package/dist/entry-path.d.ts +3 -0
- package/dist/entry-path.js +12 -0
- package/dist/index-daemon.js +3 -66
- package/dist/lifecycle.d.ts +12 -0
- package/dist/lifecycle.js +16 -0
- package/dist/maintenance-lease.d.ts +39 -0
- package/dist/maintenance-lease.js +250 -0
- package/dist/migrations/cleanup-legacy-sessions.d.ts +1 -1
- package/dist/migrations/cleanup-legacy-sessions.js +33 -15
- package/dist/official-plugins.d.ts +2 -0
- package/dist/official-plugins.js +2 -0
- package/dist/plugin-cli.d.ts +1 -3
- package/dist/plugin-cli.js +56 -45
- package/dist/plugin-host-leases.d.ts +4 -0
- package/dist/plugin-host-leases.js +7 -0
- package/dist/plugin-host-rpc.d.ts +73 -6
- package/dist/plugin-host-rpc.js +354 -81
- package/dist/plugin-installer.d.ts +24 -55
- package/dist/plugin-installer.js +258 -412
- package/dist/plugin-management-service.d.ts +30 -23
- package/dist/plugin-management-service.js +288 -105
- package/dist/plugin-marketplace.d.ts +35 -0
- package/dist/plugin-marketplace.js +299 -0
- package/dist/plugin-package.d.ts +22 -24
- package/dist/plugin-package.js +520 -571
- package/dist/plugin-skill-context.d.ts +4 -0
- package/dist/plugin-skill-context.js +35 -0
- package/dist/plugin-store.d.ts +36 -37
- package/dist/plugin-store.js +138 -92
- package/dist/plugin-supervisor.d.ts +50 -125
- package/dist/plugin-supervisor.js +678 -1030
- package/dist/pm2.d.ts +11 -2
- package/dist/pm2.js +130 -28
- package/dist/process.d.ts +12 -0
- package/dist/process.js +91 -0
- package/dist/runtime-project-store.d.ts +9 -0
- package/dist/runtime-project-store.js +83 -0
- package/dist/session-fallback-workspace.d.ts +22 -0
- package/dist/session-fallback-workspace.js +120 -0
- package/dist/session-fork-store.d.ts +41 -0
- package/dist/session-fork-store.js +288 -0
- package/dist/session-launch-operations.d.ts +23 -2
- package/dist/session-launch-operations.js +48 -7
- package/dist/session-meta-store.d.ts +12 -9
- package/dist/session-meta-store.js +50 -49
- package/dist/session-portal-grant-store.d.ts +29 -0
- package/dist/session-portal-grant-store.js +84 -0
- package/dist/setup-service.d.ts +21 -0
- package/dist/setup-service.js +39 -0
- package/dist/skills-catalog.d.ts +11 -2
- package/dist/skills-catalog.js +307 -7
- package/dist/system-dependencies.d.ts +26 -0
- package/dist/system-dependencies.js +149 -0
- package/package.json +36 -20
- package/dist/browser-cli-args.d.ts +0 -20
- package/dist/browser-cli-args.js +0 -100
- package/dist/channel-store.d.ts +0 -22
- package/dist/channel-store.js +0 -65
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -732
- package/dist/control-client.d.ts +0 -122
- package/dist/control-client.js +0 -855
- package/dist/control-endpoint.d.ts +0 -14
- package/dist/control-endpoint.js +0 -124
- package/dist/desktop-browser-host-client.d.ts +0 -35
- package/dist/desktop-browser-host-client.js +0 -415
- package/dist/instance-store.d.ts +0 -38
- package/dist/instance-store.js +0 -85
- package/dist/plugin-install-restart.d.ts +0 -13
- package/dist/plugin-install-restart.js +0 -24
- package/dist/plugin-runtime-control.d.ts +0 -2
- package/dist/plugin-runtime-control.js +0 -37
- package/dist/registry.d.ts +0 -10
- package/dist/registry.js +0 -52
- package/dist/setup.d.ts +0 -20
- package/dist/setup.js +0 -374
- package/dist/update.d.ts +0 -25
- package/dist/update.js +0 -133
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2
ADDED
|
Binary file
|
package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2
ADDED
|
Binary file
|
package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2
ADDED
|
Binary file
|
package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2
ADDED
|
Binary file
|
package/bundled-plugins/plugins/lark/ui/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2
ADDED
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Lark settings</title>
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-D8Amoe6a.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CGUVAMsv.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/dist/agent-file.js
CHANGED
|
@@ -46,7 +46,6 @@ export function scaffoldAgentSpec(id) {
|
|
|
46
46
|
instructions: "You are a helpful agent.",
|
|
47
47
|
executor: {
|
|
48
48
|
runtime: "claude",
|
|
49
|
-
model: "claude-sonnet-4-6",
|
|
50
49
|
reasoningEffort: "medium",
|
|
51
50
|
// Runtime budget (edit/remove as needed): timeout is enforced on every
|
|
52
51
|
// runtime; retry maps to per-runtime env. maxIterations (claude only) and
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { DaemonBrowserArtifactCleanResult, DaemonBrowserArtifactInstallInput, DaemonBrowserArtifactInstallResult, DaemonBrowserArtifactUpdateInput, DaemonBrowserArtifactVersionResult } from "@rynx-ai/protocol/control";
|
|
2
2
|
import { type ChromeForTestingReleaseSelector, type ResolvedChromeForTestingRelease } from "./chrome-for-testing-release-resolver.js";
|
|
3
|
-
import { type ChromeForTestingArtifactStore } from "./chrome-for-testing-store.js";
|
|
3
|
+
import { type InstalledChromeForTestingBuild, type ChromeForTestingArtifactStore } from "./chrome-for-testing-store.js";
|
|
4
|
+
import { type EnsureChromeForTestingRuntimeOptions } from "./chrome-for-testing-runtime.js";
|
|
4
5
|
export interface BrowserArtifactManagementContext {
|
|
5
6
|
signal?: AbortSignal;
|
|
7
|
+
onProgress?: (message: string) => void;
|
|
6
8
|
}
|
|
7
9
|
export interface BrowserArtifactManagementService {
|
|
8
10
|
install(input: DaemonBrowserArtifactInstallInput, context?: BrowserArtifactManagementContext): Promise<DaemonBrowserArtifactInstallResult>;
|
|
@@ -15,6 +17,7 @@ export interface BrowserArtifactManagementServiceOptions {
|
|
|
15
17
|
signal?: AbortSignal;
|
|
16
18
|
}) => Promise<ResolvedChromeForTestingRelease>;
|
|
17
19
|
createStore?: () => ChromeForTestingArtifactStore;
|
|
20
|
+
ensureRuntime?: (build: InstalledChromeForTestingBuild, options?: EnsureChromeForTestingRuntimeOptions) => Promise<void>;
|
|
18
21
|
}
|
|
19
22
|
/** Daemon-owned Browser artifact operations exposed through local management. */
|
|
20
23
|
export declare function createBrowserArtifactManagementService(options?: BrowserArtifactManagementServiceOptions): BrowserArtifactManagementService;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveChromeForTestingRelease, } from "./chrome-for-testing-release-resolver.js";
|
|
2
2
|
import { createChromeForTestingArtifactStore, } from "./chrome-for-testing-store.js";
|
|
3
|
+
import { ensureChromeForTestingRuntime, } from "./chrome-for-testing-runtime.js";
|
|
3
4
|
const MAX_PROGRESS_MESSAGES = 64;
|
|
4
5
|
const MAX_PROGRESS_MESSAGE_BYTES = 2 * 1024;
|
|
5
6
|
const MAX_PROGRESS_TOTAL_BYTES = 32 * 1024;
|
|
@@ -7,6 +8,7 @@ const MAX_PROGRESS_TOTAL_BYTES = 32 * 1024;
|
|
|
7
8
|
export function createBrowserArtifactManagementService(options = {}) {
|
|
8
9
|
const resolveRelease = options.resolveRelease ?? resolveChromeForTestingRelease;
|
|
9
10
|
const createStore = options.createStore ?? createChromeForTestingArtifactStore;
|
|
11
|
+
const ensureRuntime = options.ensureRuntime ?? ensureChromeForTestingRuntime;
|
|
10
12
|
let store;
|
|
11
13
|
const artifactStore = () => store ??= createStore();
|
|
12
14
|
const install = async (input, context = {}) => {
|
|
@@ -19,18 +21,24 @@ export function createBrowserArtifactManagementService(options = {}) {
|
|
|
19
21
|
const resolved = await resolveRelease(selector, { signal: context.signal });
|
|
20
22
|
const messages = [];
|
|
21
23
|
let messageBytes = 0;
|
|
24
|
+
const onProgress = (message) => {
|
|
25
|
+
context.onProgress?.(message);
|
|
26
|
+
if (messages.length >= MAX_PROGRESS_MESSAGES)
|
|
27
|
+
return;
|
|
28
|
+
const bounded = boundedUtf8(message, MAX_PROGRESS_MESSAGE_BYTES);
|
|
29
|
+
const bytes = Buffer.byteLength(bounded, "utf8");
|
|
30
|
+
if (messageBytes + bytes > MAX_PROGRESS_TOTAL_BYTES)
|
|
31
|
+
return;
|
|
32
|
+
messageBytes += bytes;
|
|
33
|
+
messages.push(bounded);
|
|
34
|
+
};
|
|
22
35
|
const installed = await artifactStore().installResolved(resolved, {
|
|
23
36
|
signal: context.signal,
|
|
24
|
-
onProgress
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (messageBytes + bytes > MAX_PROGRESS_TOTAL_BYTES)
|
|
30
|
-
return;
|
|
31
|
-
messageBytes += bytes;
|
|
32
|
-
messages.push(bounded);
|
|
33
|
-
},
|
|
37
|
+
onProgress,
|
|
38
|
+
verifyBeforeActivate: (build) => ensureRuntime(build, {
|
|
39
|
+
signal: context.signal,
|
|
40
|
+
onProgress,
|
|
41
|
+
}),
|
|
34
42
|
});
|
|
35
43
|
return { resolved, installed, messages };
|
|
36
44
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createBrowserArtifactManagementService, type BrowserArtifactManagementContext, type BrowserArtifactManagementService, type BrowserArtifactManagementServiceOptions, } from "./browser-artifact-management.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createBrowserArtifactManagementService, } from "./browser-artifact-management.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface EnsureBundledPluginsResult {
|
|
2
|
+
status: "ready" | "unavailable";
|
|
3
|
+
installed: string[];
|
|
4
|
+
updated: string[];
|
|
5
|
+
unchanged: string[];
|
|
6
|
+
marketplacePath?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function ensureBundledOfficialPlugins(options?: {
|
|
9
|
+
bundleDirectory?: string;
|
|
10
|
+
defaultPlugins?: readonly string[];
|
|
11
|
+
onProgress?: (message: string) => void;
|
|
12
|
+
/** Reclaim supervisor leases left by a prior daemon process. The caller
|
|
13
|
+
* must already hold the exclusive RYNX_HOME daemon-owner lock. */
|
|
14
|
+
reclaimHostLeases?: boolean;
|
|
15
|
+
}): Promise<EnsureBundledPluginsResult>;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readdirSync, renameSync, rmSync, } from "node:fs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { isAbsolute, join } from "node:path";
|
|
4
|
+
import { rynxHome } from "@rynx-ai/core";
|
|
5
|
+
import { removePluginRuntimeLease } from "@rynx-ai/plugin-sdk";
|
|
6
|
+
import { pluginDataDir, preparePluginInstallation, } from "./plugin-installer.js";
|
|
7
|
+
import { PLUGIN_HOST_RUNTIME_LEASE_IDS } from "./plugin-host-leases.js";
|
|
8
|
+
import { addPluginMarketplace, resolveMarketplacePlugin, } from "./plugin-marketplace.js";
|
|
9
|
+
import { DEFAULT_BUNDLED_PLUGINS, OFFICIAL_MARKETPLACE_ID, } from "./official-plugins.js";
|
|
10
|
+
import { getPlugin, setPluginEnabled } from "./plugin-store.js";
|
|
11
|
+
export async function ensureBundledOfficialPlugins(options = {}) {
|
|
12
|
+
const configuredBundle = options.bundleDirectory ?? process.env.RYNX_BUNDLED_PLUGINS_DIR?.trim();
|
|
13
|
+
const bundleDirectory = configuredBundle ?? fileURLToPath(new URL("../bundled-plugins", import.meta.url));
|
|
14
|
+
if (!isAbsolute(bundleDirectory)) {
|
|
15
|
+
throw new Error("bundled plugin directory must be an absolute path");
|
|
16
|
+
}
|
|
17
|
+
if (!existsSync(bundleDirectory)) {
|
|
18
|
+
if (configuredBundle) {
|
|
19
|
+
throw new Error(`bundled plugin directory not found: ${bundleDirectory}`);
|
|
20
|
+
}
|
|
21
|
+
return emptyResult("unavailable");
|
|
22
|
+
}
|
|
23
|
+
if (!lstatSync(bundleDirectory).isDirectory()) {
|
|
24
|
+
throw new Error(`bundled plugin path is not a directory: ${bundleDirectory}`);
|
|
25
|
+
}
|
|
26
|
+
const marketplacePath = syncBundledMarketplace(bundleDirectory);
|
|
27
|
+
await addPluginMarketplace(marketplacePath, {
|
|
28
|
+
allowSourceRebind: true,
|
|
29
|
+
builtIn: true,
|
|
30
|
+
onProgress: options.onProgress,
|
|
31
|
+
});
|
|
32
|
+
const result = {
|
|
33
|
+
...emptyResult("ready"),
|
|
34
|
+
marketplacePath,
|
|
35
|
+
};
|
|
36
|
+
for (const identity of options.defaultPlugins ?? DEFAULT_BUNDLED_PLUGINS) {
|
|
37
|
+
if (options.reclaimHostLeases)
|
|
38
|
+
reclaimPluginHostLeases(identity);
|
|
39
|
+
const resolved = resolveMarketplacePlugin(identity);
|
|
40
|
+
const prepared = await preparePluginInstallation(resolved.spec, options.onProgress, {
|
|
41
|
+
marketplaceId: OFFICIAL_MARKETPLACE_ID,
|
|
42
|
+
expectedId: resolved.pluginId,
|
|
43
|
+
expectedIdentity: identity,
|
|
44
|
+
});
|
|
45
|
+
try {
|
|
46
|
+
if (prepared.existing?.integrity === prepared.integrity) {
|
|
47
|
+
result.unchanged.push(identity);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const updating = Boolean(prepared.existing);
|
|
51
|
+
await prepared.commit({ expectedDigest: prepared.integrity });
|
|
52
|
+
if (!updating)
|
|
53
|
+
setPluginEnabled(identity, false);
|
|
54
|
+
(updating ? result.updated : result.installed).push(identity);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
prepared.discard();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
function reclaimPluginHostLeases(identity) {
|
|
63
|
+
const installed = getPlugin(identity);
|
|
64
|
+
if (!installed)
|
|
65
|
+
return;
|
|
66
|
+
const dataDir = pluginDataDir(installed.marketplaceId, installed.pluginId);
|
|
67
|
+
for (const leaseId of PLUGIN_HOST_RUNTIME_LEASE_IDS) {
|
|
68
|
+
removePluginRuntimeLease(dataDir, leaseId);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function syncBundledMarketplace(bundleDirectory) {
|
|
72
|
+
const distributionRoot = join(rynxHome(), "distribution");
|
|
73
|
+
const marketplacePath = join(distributionRoot, "official-market");
|
|
74
|
+
mkdirSync(distributionRoot, { recursive: true, mode: 0o700 });
|
|
75
|
+
const transactionDirectory = mkdtempSync(join(distributionRoot, "official-market-stage-"));
|
|
76
|
+
const stagedMarketplace = join(transactionDirectory, "market");
|
|
77
|
+
const backupPath = join(distributionRoot, `official-market-backup-${process.pid}-${Date.now()}`);
|
|
78
|
+
let backedUp = false;
|
|
79
|
+
try {
|
|
80
|
+
copyBundledTree(bundleDirectory, stagedMarketplace);
|
|
81
|
+
if (existsSync(marketplacePath)) {
|
|
82
|
+
renameSync(marketplacePath, backupPath);
|
|
83
|
+
backedUp = true;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
renameSync(stagedMarketplace, marketplacePath);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (backedUp && !existsSync(marketplacePath)) {
|
|
90
|
+
renameSync(backupPath, marketplacePath);
|
|
91
|
+
backedUp = false;
|
|
92
|
+
}
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
if (backedUp) {
|
|
96
|
+
rmSync(backupPath, { recursive: true, force: true });
|
|
97
|
+
backedUp = false;
|
|
98
|
+
}
|
|
99
|
+
return marketplacePath;
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
rmSync(transactionDirectory, { recursive: true, force: true });
|
|
103
|
+
if (backedUp && !existsSync(marketplacePath) && existsSync(backupPath)) {
|
|
104
|
+
renameSync(backupPath, marketplacePath);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function copyBundledTree(source, destination) {
|
|
109
|
+
const info = lstatSync(source);
|
|
110
|
+
const mode = info.mode & 0o777;
|
|
111
|
+
if (info.isSymbolicLink()) {
|
|
112
|
+
throw new Error(`bundled plugin tree must not contain symbolic links: ${source}`);
|
|
113
|
+
}
|
|
114
|
+
if (info.isDirectory()) {
|
|
115
|
+
mkdirSync(destination, { recursive: true, mode: 0o700 });
|
|
116
|
+
for (const entry of readdirSync(source)) {
|
|
117
|
+
copyBundledTree(join(source, entry), join(destination, entry));
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (!info.isFile()) {
|
|
122
|
+
throw new Error(`bundled plugin tree contains an unsupported entry: ${source}`);
|
|
123
|
+
}
|
|
124
|
+
copyFileSync(source, destination);
|
|
125
|
+
chmodSync(destination, mode);
|
|
126
|
+
}
|
|
127
|
+
function emptyResult(status) {
|
|
128
|
+
return {
|
|
129
|
+
status,
|
|
130
|
+
installed: [],
|
|
131
|
+
updated: [],
|
|
132
|
+
unchanged: [],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { InstalledChromeForTestingBuild } from "./chrome-for-testing-store.js";
|
|
2
|
+
export interface BrowserRuntimeCommandResult {
|
|
3
|
+
exitCode: number | null;
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
errorCode?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface BrowserRuntimeCommandOptions {
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
timeoutMs: number;
|
|
11
|
+
}
|
|
12
|
+
export type BrowserRuntimeCommandRunner = (command: string, args: readonly string[], options: BrowserRuntimeCommandOptions) => Promise<BrowserRuntimeCommandResult>;
|
|
13
|
+
export interface EnsureChromeForTestingRuntimeOptions {
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
onProgress?: (message: string) => void;
|
|
16
|
+
platform?: string;
|
|
17
|
+
getuid?: () => number | undefined;
|
|
18
|
+
findSystemExecutable?: (name: string) => Promise<string | undefined>;
|
|
19
|
+
runCommand?: BrowserRuntimeCommandRunner;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Verifies that a managed Chrome build can start. On Linux, known missing
|
|
23
|
+
* shared libraries are installed with a fixed package allowlist before a
|
|
24
|
+
* second probe; arbitrary output from ldd is never passed to a shell.
|
|
25
|
+
*/
|
|
26
|
+
export declare function ensureChromeForTestingRuntime(build: InstalledChromeForTestingBuild, options?: EnsureChromeForTestingRuntimeOptions): Promise<void>;
|
|
27
|
+
export declare function parseMissingSharedLibraries(output: string): string[];
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { access } from "node:fs/promises";
|
|
4
|
+
const PROBE_TIMEOUT_MS = 10_000;
|
|
5
|
+
const INSTALL_TIMEOUT_MS = 5 * 60_000;
|
|
6
|
+
const MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
7
|
+
const SYSTEM_PACKAGES = {
|
|
8
|
+
apt: {
|
|
9
|
+
"libasound.so.2": "libasound2",
|
|
10
|
+
"libatk-1.0.so.0": "libatk1.0-0",
|
|
11
|
+
"libatk-bridge-2.0.so.0": "libatk-bridge2.0-0",
|
|
12
|
+
"libatspi.so.0": "libatspi2.0-0",
|
|
13
|
+
"libcairo.so.2": "libcairo2",
|
|
14
|
+
"libcups.so.2": "libcups2",
|
|
15
|
+
"libdbus-1.so.3": "libdbus-1-3",
|
|
16
|
+
"libdrm.so.2": "libdrm2",
|
|
17
|
+
"libexpat.so.1": "libexpat1",
|
|
18
|
+
"libfontconfig.so.1": "libfontconfig1",
|
|
19
|
+
"libfreetype.so.6": "libfreetype6",
|
|
20
|
+
"libgbm.so.1": "libgbm1",
|
|
21
|
+
"libglib-2.0.so.0": "libglib2.0-0",
|
|
22
|
+
"libgobject-2.0.so.0": "libglib2.0-0",
|
|
23
|
+
"libgtk-3.so.0": "libgtk-3-0",
|
|
24
|
+
"libnspr4.so": "libnspr4",
|
|
25
|
+
"libnss3.so": "libnss3",
|
|
26
|
+
"libpango-1.0.so.0": "libpango-1.0-0",
|
|
27
|
+
"libX11.so.6": "libx11-6",
|
|
28
|
+
"libxcb.so.1": "libxcb1",
|
|
29
|
+
"libXcomposite.so.1": "libxcomposite1",
|
|
30
|
+
"libXdamage.so.1": "libxdamage1",
|
|
31
|
+
"libXext.so.6": "libxext6",
|
|
32
|
+
"libXfixes.so.3": "libxfixes3",
|
|
33
|
+
"libxkbcommon.so.0": "libxkbcommon0",
|
|
34
|
+
"libXrandr.so.2": "libxrandr2",
|
|
35
|
+
},
|
|
36
|
+
rpm: {
|
|
37
|
+
"libasound.so.2": "alsa-lib",
|
|
38
|
+
"libatk-1.0.so.0": "atk",
|
|
39
|
+
"libatk-bridge-2.0.so.0": "at-spi2-atk",
|
|
40
|
+
"libatspi.so.0": "at-spi2-core",
|
|
41
|
+
"libcairo.so.2": "cairo",
|
|
42
|
+
"libcups.so.2": "cups-libs",
|
|
43
|
+
"libdbus-1.so.3": "dbus-libs",
|
|
44
|
+
"libdrm.so.2": "libdrm",
|
|
45
|
+
"libexpat.so.1": "expat",
|
|
46
|
+
"libfontconfig.so.1": "fontconfig",
|
|
47
|
+
"libfreetype.so.6": "freetype",
|
|
48
|
+
"libgbm.so.1": "mesa-libgbm",
|
|
49
|
+
"libglib-2.0.so.0": "glib2",
|
|
50
|
+
"libgobject-2.0.so.0": "glib2",
|
|
51
|
+
"libgtk-3.so.0": "gtk3",
|
|
52
|
+
"libnspr4.so": "nspr",
|
|
53
|
+
"libnss3.so": "nss",
|
|
54
|
+
"libpango-1.0.so.0": "pango",
|
|
55
|
+
"libX11.so.6": "libX11",
|
|
56
|
+
"libxcb.so.1": "libxcb",
|
|
57
|
+
"libXcomposite.so.1": "libXcomposite",
|
|
58
|
+
"libXdamage.so.1": "libXdamage",
|
|
59
|
+
"libXext.so.6": "libXext",
|
|
60
|
+
"libXfixes.so.3": "libXfixes",
|
|
61
|
+
"libxkbcommon.so.0": "libxkbcommon",
|
|
62
|
+
"libXrandr.so.2": "libXrandr",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Verifies that a managed Chrome build can start. On Linux, known missing
|
|
67
|
+
* shared libraries are installed with a fixed package allowlist before a
|
|
68
|
+
* second probe; arbitrary output from ldd is never passed to a shell.
|
|
69
|
+
*/
|
|
70
|
+
export async function ensureChromeForTestingRuntime(build, options = {}) {
|
|
71
|
+
const runCommand = options.runCommand ?? runBrowserRuntimeCommand;
|
|
72
|
+
const findSystemExecutable = options.findSystemExecutable ?? findSystemCommand;
|
|
73
|
+
const run = async (command, args, timeoutMs = PROBE_TIMEOUT_MS) => {
|
|
74
|
+
options.signal?.throwIfAborted();
|
|
75
|
+
const result = await runCommand(command, args, { signal: options.signal, timeoutMs });
|
|
76
|
+
options.signal?.throwIfAborted();
|
|
77
|
+
return result;
|
|
78
|
+
};
|
|
79
|
+
const initialProbe = await run(build.executablePath, ["--version"]);
|
|
80
|
+
if (initialProbe.exitCode === 0) {
|
|
81
|
+
options.onProgress?.(`verified Chrome for Testing ${build.version} can start`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if ((options.platform ?? process.platform) !== "linux") {
|
|
85
|
+
throw browserLaunchError(build, initialProbe);
|
|
86
|
+
}
|
|
87
|
+
const ldd = await findSystemExecutable("ldd");
|
|
88
|
+
if (!ldd) {
|
|
89
|
+
throw new Error(`${browserLaunchError(build, initialProbe).message}; ldd is unavailable`);
|
|
90
|
+
}
|
|
91
|
+
const dependencyCheck = await run(ldd, [build.executablePath]);
|
|
92
|
+
const missingLibraries = parseMissingSharedLibraries(`${dependencyCheck.stdout}\n${dependencyCheck.stderr}`);
|
|
93
|
+
if (missingLibraries.length === 0)
|
|
94
|
+
throw browserLaunchError(build, initialProbe);
|
|
95
|
+
const packageManager = await resolvePackageManager(findSystemExecutable);
|
|
96
|
+
if (!packageManager) {
|
|
97
|
+
throw new Error(`Chrome for Testing is missing ${missingLibraries.join(", ")}, ` +
|
|
98
|
+
"but no supported system package manager (apt-get, dnf, or yum) is available");
|
|
99
|
+
}
|
|
100
|
+
const packages = packagesForLibraries(packageManager.family, missingLibraries);
|
|
101
|
+
const installArgs = packageManager.family === "apt"
|
|
102
|
+
? ["install", "-y", "--no-install-recommends", ...packages]
|
|
103
|
+
: ["install", "-y", ...packages];
|
|
104
|
+
let command = packageManager.path;
|
|
105
|
+
let args = installArgs;
|
|
106
|
+
const getuid = options.getuid ?? (() => process.getuid?.());
|
|
107
|
+
if (getuid() !== 0) {
|
|
108
|
+
const sudo = await findSystemExecutable("sudo");
|
|
109
|
+
if (!sudo || (await run(sudo, ["-n", "true"])).exitCode !== 0) {
|
|
110
|
+
throw new Error(`Chrome for Testing is missing ${missingLibraries.join(", ")}. ` +
|
|
111
|
+
`Install these packages as an administrator and retry: ${packages.join(" ")}`);
|
|
112
|
+
}
|
|
113
|
+
command = sudo;
|
|
114
|
+
args = ["-n", packageManager.path, ...installArgs];
|
|
115
|
+
}
|
|
116
|
+
options.onProgress?.(`installing Chrome for Testing system dependencies: ${packages.join(" ")}`);
|
|
117
|
+
const installation = await run(command, args, INSTALL_TIMEOUT_MS);
|
|
118
|
+
if (installation.exitCode !== 0) {
|
|
119
|
+
throw new Error(`failed to install Chrome for Testing system dependencies (${packages.join(" ")}): ` +
|
|
120
|
+
commandFailure(installation));
|
|
121
|
+
}
|
|
122
|
+
const finalProbe = await run(build.executablePath, ["--version"]);
|
|
123
|
+
if (finalProbe.exitCode !== 0)
|
|
124
|
+
throw browserLaunchError(build, finalProbe);
|
|
125
|
+
options.onProgress?.(`verified Chrome for Testing ${build.version} can start`);
|
|
126
|
+
}
|
|
127
|
+
export function parseMissingSharedLibraries(output) {
|
|
128
|
+
const libraries = new Set();
|
|
129
|
+
for (const line of output.split(/\r?\n/u)) {
|
|
130
|
+
const match = /^\s*(\S+)\s+=>\s+not found\s*$/u.exec(line);
|
|
131
|
+
if (match?.[1])
|
|
132
|
+
libraries.add(match[1]);
|
|
133
|
+
}
|
|
134
|
+
return [...libraries].sort();
|
|
135
|
+
}
|
|
136
|
+
function packagesForLibraries(family, libraries) {
|
|
137
|
+
const mapping = SYSTEM_PACKAGES[family];
|
|
138
|
+
const unsupported = libraries.filter((library) => !mapping[library]);
|
|
139
|
+
if (unsupported.length > 0) {
|
|
140
|
+
throw new Error(`Chrome for Testing is missing unsupported system libraries: ${unsupported.join(", ")}`);
|
|
141
|
+
}
|
|
142
|
+
return [...new Set(libraries.map((library) => mapping[library]))].sort();
|
|
143
|
+
}
|
|
144
|
+
async function resolvePackageManager(findExecutable) {
|
|
145
|
+
const apt = await findExecutable("apt-get");
|
|
146
|
+
if (apt)
|
|
147
|
+
return { family: "apt", path: apt };
|
|
148
|
+
const dnf = await findExecutable("dnf");
|
|
149
|
+
if (dnf)
|
|
150
|
+
return { family: "rpm", path: dnf };
|
|
151
|
+
const yum = await findExecutable("yum");
|
|
152
|
+
return yum ? { family: "rpm", path: yum } : undefined;
|
|
153
|
+
}
|
|
154
|
+
async function findSystemCommand(name) {
|
|
155
|
+
for (const directory of ["/usr/bin", "/bin", "/usr/sbin", "/sbin"]) {
|
|
156
|
+
const candidate = `${directory}/${name}`;
|
|
157
|
+
try {
|
|
158
|
+
await access(candidate, constants.X_OK);
|
|
159
|
+
return candidate;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Try the next standard system directory.
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
function runBrowserRuntimeCommand(command, args, options) {
|
|
168
|
+
return new Promise((resolveResult) => {
|
|
169
|
+
execFile(command, [...args], {
|
|
170
|
+
encoding: "utf8",
|
|
171
|
+
env: { ...process.env, LC_ALL: "C" },
|
|
172
|
+
maxBuffer: MAX_OUTPUT_BYTES,
|
|
173
|
+
signal: options.signal,
|
|
174
|
+
timeout: options.timeoutMs,
|
|
175
|
+
}, (error, stdout, stderr) => {
|
|
176
|
+
resolveResult({
|
|
177
|
+
exitCode: error
|
|
178
|
+
? typeof error.code === "number" ? error.code : null
|
|
179
|
+
: 0,
|
|
180
|
+
stdout,
|
|
181
|
+
stderr,
|
|
182
|
+
...(error && typeof error.code === "string" ? { errorCode: error.code } : {}),
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function browserLaunchError(build, result) {
|
|
188
|
+
return new Error(`Chrome for Testing ${build.version} was installed but cannot start: ${commandFailure(result)}`);
|
|
189
|
+
}
|
|
190
|
+
function commandFailure(result) {
|
|
191
|
+
const detail = result.stderr.trim() || result.stdout.trim() || result.errorCode;
|
|
192
|
+
return detail ? detail.slice(0, 2_000) : `exit code ${result.exitCode ?? "unknown"}`;
|
|
193
|
+
}
|
|
@@ -58,6 +58,8 @@ export interface ChromeForTestingArtifactStoreOptions {
|
|
|
58
58
|
export interface InstallChromeForTestingOptions {
|
|
59
59
|
signal?: AbortSignal;
|
|
60
60
|
onProgress?: (message: string) => void;
|
|
61
|
+
/** Runs after the build is complete but before it becomes active. */
|
|
62
|
+
verifyBeforeActivate?: (build: InstalledChromeForTestingBuild) => Promise<void>;
|
|
61
63
|
}
|
|
62
64
|
export interface PruneChromeForTestingStagingOptions {
|
|
63
65
|
olderThanMs?: number;
|
|
@@ -86,6 +86,11 @@ export function createChromeForTestingArtifactStore(options = {}) {
|
|
|
86
86
|
});
|
|
87
87
|
};
|
|
88
88
|
const installDownloadedBuild = async (release, expectedSha256, installOptions) => {
|
|
89
|
+
const verifyBeforeActivate = async (build) => {
|
|
90
|
+
throwIfAborted(installOptions.signal);
|
|
91
|
+
await installOptions.verifyBeforeActivate?.(build);
|
|
92
|
+
throwIfAborted(installOptions.signal);
|
|
93
|
+
};
|
|
89
94
|
const paths = ensureStorePaths(rootDir, platform.hostPlatform);
|
|
90
95
|
if (expectedSha256 !== undefined) {
|
|
91
96
|
const finalPath = buildPath(paths.buildsRoot, release.version, expectedSha256);
|
|
@@ -94,6 +99,7 @@ export function createChromeForTestingArtifactStore(options = {}) {
|
|
|
94
99
|
sha256: expectedSha256,
|
|
95
100
|
});
|
|
96
101
|
if (existing) {
|
|
102
|
+
await verifyBeforeActivate(existing);
|
|
97
103
|
writeActiveManifest(paths.root, existing);
|
|
98
104
|
return existing;
|
|
99
105
|
}
|
|
@@ -105,6 +111,7 @@ export function createChromeForTestingArtifactStore(options = {}) {
|
|
|
105
111
|
if (active?.version === release.version &&
|
|
106
112
|
active.artifactPlatform === release.platform &&
|
|
107
113
|
active.sourceUrl === release.url) {
|
|
114
|
+
await verifyBeforeActivate(active);
|
|
108
115
|
return active;
|
|
109
116
|
}
|
|
110
117
|
}
|
|
@@ -134,6 +141,7 @@ export function createChromeForTestingArtifactStore(options = {}) {
|
|
|
134
141
|
const finalPath = buildPath(paths.buildsRoot, build.version, build.sha256);
|
|
135
142
|
const existing = readInstalledBuild(finalPath, paths.buildsRoot, platform, build);
|
|
136
143
|
if (existing) {
|
|
144
|
+
await verifyBeforeActivate(existing);
|
|
137
145
|
writeActiveManifest(paths.root, existing);
|
|
138
146
|
return existing;
|
|
139
147
|
}
|
|
@@ -164,6 +172,7 @@ export function createChromeForTestingArtifactStore(options = {}) {
|
|
|
164
172
|
throw error;
|
|
165
173
|
}
|
|
166
174
|
const installed = requireInstalledBuild(finalPath, paths.buildsRoot, platform, build);
|
|
175
|
+
await verifyBeforeActivate(installed);
|
|
167
176
|
writeActiveManifest(paths.root, installed);
|
|
168
177
|
installOptions.onProgress?.(`installed Chrome for Testing ${build.version} (${build.sha256})`);
|
|
169
178
|
return installed;
|
package/dist/control-deps.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
1
|
+
import { type AgentRuntimeId, type AppConfig } from "@rynx-ai/core";
|
|
2
|
+
import { type ControlPlaneDeps } from "@rynx-ai/server";
|
|
3
|
+
import type { ControlAgentModelOption } from "@rynx-ai/protocol/control";
|
|
4
|
+
export declare function buildControlDeps(config: AppConfig): ControlPlaneDeps;
|
|
5
|
+
/** Project a Runtime-native model catalog into the control-plane option shape. */
|
|
6
|
+
export declare function listControlAgentModels(config: AppConfig, runtime: AgentRuntimeId): Promise<ControlAgentModelOption[]>;
|