@rynx-ai/daemon 0.1.11-beta.2 → 0.1.11-beta.21
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/plugins/lark/.rynx-plugin/plugin.json +0 -12
- package/bundled-plugins/plugins/lark/dist/cli-mirror/mirror-index.js +3 -1
- package/bundled-plugins/plugins/lark/dist/host-adapters.d.ts +3 -3
- package/bundled-plugins/plugins/lark/dist/host-adapters.js +20 -18
- package/bundled-plugins/plugins/lark/dist/lark.js +18 -12
- package/bundled-plugins/plugins/lark/dist/runtime.js +6046 -6022
- package/bundled-plugins/plugins/lark/dist/settings.js +6006 -5988
- package/bundled-plugins/plugins/lark/package.json +1 -1
- package/bundled-plugins/plugins/lark/ui/assets/index-CGUVAMsv.css +1 -0
- package/bundled-plugins/plugins/lark/ui/index.html +2 -2
- package/dist/agent-file.js +0 -1
- package/dist/browser-artifact-management.d.ts +4 -1
- package/dist/browser-artifact-management.js +22 -11
- package/dist/browser-artifacts.d.ts +1 -0
- package/dist/browser-artifacts.js +1 -0
- package/dist/chrome-for-testing-runtime.d.ts +27 -0
- package/dist/chrome-for-testing-runtime.js +194 -0
- package/dist/chrome-for-testing-store.d.ts +2 -0
- package/dist/chrome-for-testing-store.js +37 -6
- package/dist/control-deps.d.ts +6 -2
- package/dist/control-deps.js +87 -4
- package/dist/control-link-store.js +4 -3
- package/dist/daemon-owner.js +4 -7
- package/dist/daemon-server.d.ts +4 -1
- package/dist/daemon-server.js +158 -45
- package/dist/db.d.ts +2 -2
- package/dist/db.js +55 -20
- package/dist/entry-path.d.ts +3 -0
- package/dist/entry-path.js +12 -0
- package/dist/index-daemon.js +3 -87
- package/dist/lifecycle.d.ts +13 -0
- package/dist/lifecycle.js +19 -0
- package/dist/maintenance-lease.d.ts +39 -0
- package/dist/maintenance-lease.js +250 -0
- package/dist/migrations/cleanup-legacy-sessions.js +4 -3
- package/dist/plugin-cli.d.ts +10 -0
- package/dist/plugin-cli.js +19 -2
- package/dist/plugin-host-rpc.d.ts +35 -6
- package/dist/plugin-host-rpc.js +222 -59
- package/dist/plugin-installer.js +62 -2
- package/dist/plugin-management-service.js +0 -2
- package/dist/plugin-marketplace.js +2 -1
- package/dist/plugin-store.js +2 -4
- package/dist/plugin-supervisor.d.ts +5 -0
- package/dist/plugin-supervisor.js +218 -33
- package/dist/pm2.d.ts +11 -2
- package/dist/pm2.js +116 -19
- package/dist/process.d.ts +12 -0
- package/dist/process.js +91 -0
- package/dist/remote-runtime-access-store.d.ts +2 -2
- package/dist/remote-runtime-access-store.js +6 -9
- package/dist/remote-runtime-target-store.d.ts +2 -2
- package/dist/remote-runtime-target-store.js +6 -6
- package/dist/session-emulator-binding-store.js +4 -6
- package/dist/session-fork-store.js +24 -8
- package/dist/session-launch-operations.d.ts +10 -1
- package/dist/session-launch-operations.js +21 -11
- package/dist/session-log-store.js +2 -1
- package/dist/session-meta-store.d.ts +5 -0
- package/dist/session-meta-store.js +25 -2
- package/dist/session-portal-grant-store.d.ts +29 -0
- package/dist/session-portal-grant-store.js +85 -0
- package/dist/session-resource-store.js +3 -2
- 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 -10
- package/dist/sqlite.d.ts +22 -0
- package/dist/sqlite.js +57 -0
- package/dist/system-dependencies.d.ts +22 -0
- package/dist/system-dependencies.js +79 -0
- package/package.json +37 -21
- package/bundled-plugins/plugins/lark/ui/assets/index-B2dhMlMU.css +0 -1
- package/dist/browser-cli-args.d.ts +0 -20
- package/dist/browser-cli-args.js +0 -100
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -550
- 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/setup.d.ts +0 -20
- package/dist/setup.js +0 -386
- package/dist/update.d.ts +0 -25
- package/dist/update.js +0 -133
- /package/bundled-plugins/plugins/lark/ui/assets/{index-D9N-AkLX.js → index-D8Amoe6a.js} +0 -0
package/dist/cli.js
DELETED
|
@@ -1,550 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* `rynx` — the daemon CLI.
|
|
4
|
-
*
|
|
5
|
-
* rynx start | stop | restart | status | logs process lifecycle (pm2)
|
|
6
|
-
* rynx market add|list|remove|refresh ...
|
|
7
|
-
* rynx plugin install|list|update|uninstall|enable|disable ...
|
|
8
|
-
* rynx plugin <plugin-id>@<marketplace-id> <plugin-command> ...
|
|
9
|
-
* rynx agent list | show <name> | add <name> | rm <name>
|
|
10
|
-
*
|
|
11
|
-
* The CLI owns process lifecycle and file-based declarative agent specs.
|
|
12
|
-
* Plugin and Market mutations go through the resident daemon management API.
|
|
13
|
-
*
|
|
14
|
-
* Hand-rolled arg dispatch (no arg-parser dep) to match the repo's zero-dep CLI
|
|
15
|
-
* style.
|
|
16
|
-
*/
|
|
17
|
-
import { spawn } from "node:child_process";
|
|
18
|
-
import { existsSync } from "node:fs";
|
|
19
|
-
import { createRequire } from "node:module";
|
|
20
|
-
import path from "node:path";
|
|
21
|
-
import { runCli as runModernCli } from "@rynx-ai/cli";
|
|
22
|
-
import { listAgentSpecs, loadAgentSpec, loadConfig, rynxAgentsDir } from "@rynx-ai/core";
|
|
23
|
-
import { encodePairingCode } from "@rynx-ai/protocol/direct-runtime";
|
|
24
|
-
import { agentSpecPath, removeAgentSpec, scaffoldAgentSpec } from "./agent-file.js";
|
|
25
|
-
import { parseBrowserCliArgs, resolveBrowserCliTarget, } from "./browser-cli-args.js";
|
|
26
|
-
import { resolveChromeForTestingRelease } from "./chrome-for-testing-release-resolver.js";
|
|
27
|
-
import { createChromeForTestingArtifactStore } from "./chrome-for-testing-store.js";
|
|
28
|
-
import { cleanupLegacySessions } from "./migrations/cleanup-legacy-sessions.js";
|
|
29
|
-
import { startDaemon, statusDaemon, stopDaemon, streamLogs } from "./pm2.js";
|
|
30
|
-
import { runDoctor, runSetup } from "./setup.js";
|
|
31
|
-
import { runUpdate } from "./update.js";
|
|
32
|
-
import { createResidentRemoteRuntimePairingOffer, callManagedRuntimeBrowser, callResidentRuntime, forgetResidentRuntimeTarget, getResidentRuntimeLocalBrowserEndpoint, listResidentRemoteRuntimeClients, listResidentRuntimeTargets, pairResidentRuntimeTarget, revokeResidentRemoteRuntimeClient, readOptionalManagedRuntimeBrowserCredential, testResidentRuntimeTarget, } from "./control-client.js";
|
|
33
|
-
const USAGE = `Usage: rynx <command>
|
|
34
|
-
|
|
35
|
-
Setup:
|
|
36
|
-
setup interactive wizard — configure ~/.rynx/config.json step by step
|
|
37
|
-
doctor read-only health check (creates nothing; non-zero on failure)
|
|
38
|
-
|
|
39
|
-
Lifecycle:
|
|
40
|
-
start start the resident server (pm2-supervised)
|
|
41
|
-
restart reload the running server
|
|
42
|
-
stop stop and remove the server
|
|
43
|
-
status print whether the server is running
|
|
44
|
-
logs tail the server logs
|
|
45
|
-
update [version] upgrade @rynx-ai/daemon (npm) + restart (--check: report only)
|
|
46
|
-
|
|
47
|
-
Plugin marketplaces:
|
|
48
|
-
market add <git|path> [--alias <id>]
|
|
49
|
-
market list
|
|
50
|
-
market refresh [id]
|
|
51
|
-
market remove <id>
|
|
52
|
-
|
|
53
|
-
Plugins:
|
|
54
|
-
plugin list
|
|
55
|
-
plugin install <git|path|plugin@market> [--force]
|
|
56
|
-
plugin update <plugin@market>
|
|
57
|
-
plugin uninstall <plugin@market>
|
|
58
|
-
plugin enable|disable <plugin@market>
|
|
59
|
-
plugin <plugin@market> <command> [args...]
|
|
60
|
-
|
|
61
|
-
Agents (~/.rynx/agents/<id>/agent.json — dir name is the id):
|
|
62
|
-
agent list list agents (id · runtime · model · [display name])
|
|
63
|
-
agent show <id> print a parsed + validated agent spec
|
|
64
|
-
agent add <id> scaffold an agent dir + starter spec, then edit it
|
|
65
|
-
agent rm <id> remove an agent (its whole config dir)
|
|
66
|
-
(select an agent in a chat with \`/agent <id>\`;
|
|
67
|
-
set a fleet default via the RYNX_DEFAULT_AGENT env var)
|
|
68
|
-
|
|
69
|
-
Maintenance:
|
|
70
|
-
cleanup sessions [--dry-run]
|
|
71
|
-
delete legacy (pre-uuid) sessions so the system starts
|
|
72
|
-
clean on opaque ids (runs once at boot too). Stop the
|
|
73
|
-
daemon before running manually.
|
|
74
|
-
|
|
75
|
-
Emulator:
|
|
76
|
-
emulator <args…> passthrough to the bundled \`rynx-emulator\` CLI
|
|
77
|
-
(use --runtime <local|daemon-id> for bounded unary
|
|
78
|
-
remote control; run \`rynx emulator\` for its help)
|
|
79
|
-
|
|
80
|
-
Remote Runtime:
|
|
81
|
-
runtime share --address <host|ws-url> [--label <label>] [--json]
|
|
82
|
-
on the remote host, print one revocable pairing link
|
|
83
|
-
runtime pair [...] compatibility alias for runtime share
|
|
84
|
-
runtime add --pairing-code <rynx://...> [--name <name>]
|
|
85
|
-
pair, verify and save a remote daemon
|
|
86
|
-
(stdin remains supported for scripts)
|
|
87
|
-
runtime list [--json] list the synthetic local target and paired daemons
|
|
88
|
-
runtime test <local|daemon-id> [--json]
|
|
89
|
-
authenticate and read the selected daemon status
|
|
90
|
-
runtime forget <daemon-id>
|
|
91
|
-
remove one local target and its client credential
|
|
92
|
-
runtime clients list [--json]
|
|
93
|
-
runtime clients revoke <grant-id>
|
|
94
|
-
inspect/revoke clients authorized by this daemon
|
|
95
|
-
|
|
96
|
-
Browser (one Browser per Runtime Session):
|
|
97
|
-
browser install [--channel <stable|beta|dev|canary> | --version <x.x.x.x>] [--json]
|
|
98
|
-
install and activate managed Chrome for Testing
|
|
99
|
-
browser update [--channel <stable|beta|dev|canary>] [--json]
|
|
100
|
-
resolve and activate the current channel build
|
|
101
|
-
browser version [--json]
|
|
102
|
-
show the active managed Browser engine
|
|
103
|
-
browser clean [--json] remove inactive managed builds while retaining active,
|
|
104
|
-
rollback, and live Headless Browser builds
|
|
105
|
-
browser open [url] [--session <id>] [--runtime <local|daemon-id>] [--json]
|
|
106
|
-
open the selected Runtime Session's managed Browser
|
|
107
|
-
browser status [--session <id>] [--runtime <local|daemon-id>] [--json]
|
|
108
|
-
show Browser generation, state and active Page
|
|
109
|
-
browser pages [--session <id>] [--runtime <local|daemon-id>] [--json]
|
|
110
|
-
list the Browser's opaque Pages
|
|
111
|
-
browser endpoint [--ensure] [--session <local-id>] [--json]
|
|
112
|
-
print Runtime-local CDP; --ensure opens it when absent
|
|
113
|
-
browser close [--session <id>] [--runtime <local|daemon-id>] [--json]
|
|
114
|
-
close the current Browser generation
|
|
115
|
-
|
|
116
|
-
Plugin-owned settings and channel instances are configured from each plugin's
|
|
117
|
-
management interface (run \`rynx start\`, then open the printed URL).
|
|
118
|
-
`;
|
|
119
|
-
function fail(message) {
|
|
120
|
-
console.error(message);
|
|
121
|
-
process.exit(2);
|
|
122
|
-
}
|
|
123
|
-
async function agentCommand(sub, name) {
|
|
124
|
-
switch (sub) {
|
|
125
|
-
case "list": {
|
|
126
|
-
const specs = await listAgentSpecs();
|
|
127
|
-
console.log(`Agents (dir: ${rynxAgentsDir()})`);
|
|
128
|
-
if (specs.length === 0) {
|
|
129
|
-
console.log(" (none)");
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
for (const spec of specs) {
|
|
133
|
-
const runtime = spec.executor?.runtime ?? "(default)";
|
|
134
|
-
const model = spec.executor?.model ?? "(default)";
|
|
135
|
-
const display = spec.name && spec.name !== spec.id ? ` (${spec.name})` : "";
|
|
136
|
-
console.log(` ${spec.id.padEnd(16)} ${runtime.padEnd(8)} ${model}${display}`);
|
|
137
|
-
}
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
case "show": {
|
|
141
|
-
if (!name)
|
|
142
|
-
fail("agent show: missing agent name");
|
|
143
|
-
const spec = await loadAgentSpec(name);
|
|
144
|
-
if (!spec)
|
|
145
|
-
fail(`agent "${name}" not found at ${agentSpecPath(name)}`);
|
|
146
|
-
console.log(JSON.stringify(spec, null, 2));
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
case "add": {
|
|
150
|
-
if (!name)
|
|
151
|
-
fail("agent add: missing agent name");
|
|
152
|
-
if (existsSync(agentSpecPath(name)))
|
|
153
|
-
fail(`agent "${name}" already exists at ${agentSpecPath(name)}`);
|
|
154
|
-
scaffoldAgentSpec(name);
|
|
155
|
-
console.log(`Agent "${name}" created at ${agentSpecPath(name)}. Edit it, then select it in a chat with \`/agent ${name}\`.`);
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
case "rm":
|
|
159
|
-
case "remove": {
|
|
160
|
-
if (!name)
|
|
161
|
-
fail("agent rm: missing agent name");
|
|
162
|
-
if (!removeAgentSpec(name))
|
|
163
|
-
fail(`agent "${name}" not found`);
|
|
164
|
-
console.log(`Agent "${name}" removed.`);
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
default:
|
|
168
|
-
fail(USAGE);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
async function cleanupCommand(sub) {
|
|
172
|
-
if (sub !== "sessions")
|
|
173
|
-
fail("cleanup: only `cleanup sessions` is supported");
|
|
174
|
-
const dryRun = process.argv.includes("--dry-run");
|
|
175
|
-
const result = cleanupLegacySessions({
|
|
176
|
-
codexStorePath: loadConfig().AGENT_SESSION_STORE_PATH,
|
|
177
|
-
dryRun,
|
|
178
|
-
log: (entry) => console.log(JSON.stringify(entry)),
|
|
179
|
-
});
|
|
180
|
-
const summary = `${result.deletedSessions} session(s), ${result.deletedLogRows} log row(s), ${result.prunedStoreEntries} store entr(ies)`;
|
|
181
|
-
console.log(dryRun ? `Dry run: would delete ${summary}.` : `Deleted ${summary}.`);
|
|
182
|
-
}
|
|
183
|
-
/** Pass `rynx emulator <args…>` through to the dependency's own CLI, verbatim.
|
|
184
|
-
* Resolved from @rynx-ai/emulator (dist/cli.js sits beside the main entry), so it
|
|
185
|
-
* runs the exact locked version — no PATH or npx involved. Stdio is inherited
|
|
186
|
-
* so interactive flows (the skill install agent picker) work. */
|
|
187
|
-
function emulatorPassthrough(args) {
|
|
188
|
-
const require = createRequire(import.meta.url);
|
|
189
|
-
const cliPath = path.join(path.dirname(require.resolve("@rynx-ai/emulator")), "cli.js");
|
|
190
|
-
const child = spawn(process.execPath, [cliPath, ...args], { stdio: "inherit" });
|
|
191
|
-
child.on("exit", (code) => process.exit(code ?? 1));
|
|
192
|
-
child.on("error", (error) => {
|
|
193
|
-
console.error(`rynx emulator: failed to launch the bundled CLI: ${error.message}`);
|
|
194
|
-
process.exit(1);
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
async function runtimeCommand(args) {
|
|
198
|
-
const [sub, arg] = args;
|
|
199
|
-
const json = args.includes("--json");
|
|
200
|
-
switch (sub) {
|
|
201
|
-
case "share":
|
|
202
|
-
case "pair": {
|
|
203
|
-
const label = optionValue(args, "--label");
|
|
204
|
-
const address = optionValue(args, "--address");
|
|
205
|
-
if (!address) {
|
|
206
|
-
fail("runtime share: pass --address with a host or ws(s) URL reachable by the other device");
|
|
207
|
-
}
|
|
208
|
-
const offer = await createResidentRemoteRuntimePairingOffer({
|
|
209
|
-
...(label ? { clientLabel: label } : {}),
|
|
210
|
-
address,
|
|
211
|
-
});
|
|
212
|
-
console.log(json ? JSON.stringify(offer, null, 2) : encodePairingCode(offer));
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
case "add": {
|
|
216
|
-
const name = optionValue(args, "--name");
|
|
217
|
-
const code = optionValue(args, "--pairing-code");
|
|
218
|
-
if (code === undefined && process.stdin.isTTY) {
|
|
219
|
-
fail("runtime add: pass --pairing-code or pipe a pairing link on stdin");
|
|
220
|
-
}
|
|
221
|
-
const raw = code ?? await readStdinBounded(64 * 1024);
|
|
222
|
-
if (!raw.trim()) {
|
|
223
|
-
fail("runtime add: pass --pairing-code or pipe a pairing link on stdin");
|
|
224
|
-
}
|
|
225
|
-
let offer = raw.trim();
|
|
226
|
-
if (raw.trim().startsWith("{")) {
|
|
227
|
-
try {
|
|
228
|
-
offer = JSON.parse(raw);
|
|
229
|
-
}
|
|
230
|
-
catch {
|
|
231
|
-
fail("runtime add: stdin is not valid pairing JSON");
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
const result = await pairResidentRuntimeTarget(offer, name);
|
|
235
|
-
if (json)
|
|
236
|
-
console.log(JSON.stringify(result, null, 2));
|
|
237
|
-
else {
|
|
238
|
-
console.log(`Paired ${result.target.displayName} (${result.target.daemonId}) via ${result.target.endpoint}.`);
|
|
239
|
-
console.log(`Remote instance: ${result.status.daemonInstanceId}`);
|
|
240
|
-
}
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
case "list": {
|
|
244
|
-
const targets = await listResidentRuntimeTargets();
|
|
245
|
-
if (json) {
|
|
246
|
-
console.log(JSON.stringify({ runtimes: targets }, null, 2));
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
console.log("Runtime targets");
|
|
250
|
-
for (const target of targets) {
|
|
251
|
-
const route = target.binding === "local" ? "local" : target.endpoint;
|
|
252
|
-
console.log(` ${target.selector.padEnd(38)} ${target.displayName} ${route}`);
|
|
253
|
-
}
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
case "test": {
|
|
257
|
-
if (!arg || arg.startsWith("--"))
|
|
258
|
-
fail("runtime test: missing local or daemon id");
|
|
259
|
-
const result = await testResidentRuntimeTarget(arg);
|
|
260
|
-
if (json)
|
|
261
|
-
console.log(JSON.stringify(result, null, 2));
|
|
262
|
-
else {
|
|
263
|
-
console.log(`${result.target.displayName}: connected to ${result.status.daemonId} ` +
|
|
264
|
-
`(instance ${result.status.daemonInstanceId})`);
|
|
265
|
-
}
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
case "forget": {
|
|
269
|
-
if (!arg || arg.startsWith("--"))
|
|
270
|
-
fail("runtime forget: missing daemon id");
|
|
271
|
-
await forgetResidentRuntimeTarget(arg);
|
|
272
|
-
console.log(`Forgot Runtime target ${arg}.`);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
case "clients": {
|
|
276
|
-
const action = arg;
|
|
277
|
-
if (action === "list") {
|
|
278
|
-
const clients = await listResidentRemoteRuntimeClients();
|
|
279
|
-
if (json) {
|
|
280
|
-
console.log(JSON.stringify({ clients }, null, 2));
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
console.log("Remote Runtime clients");
|
|
284
|
-
if (clients.length === 0)
|
|
285
|
-
console.log(" (none)");
|
|
286
|
-
for (const client of clients) {
|
|
287
|
-
const state = client.revokedAt ? "revoked" : "active";
|
|
288
|
-
console.log(` ${client.grantId.padEnd(38)} ${client.clientLabel ?? client.clientId} ${state}`);
|
|
289
|
-
}
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
if (action === "revoke") {
|
|
293
|
-
const grantId = args[2];
|
|
294
|
-
if (!grantId || grantId.startsWith("--")) {
|
|
295
|
-
fail("runtime clients revoke: missing grant id");
|
|
296
|
-
}
|
|
297
|
-
const result = await revokeResidentRemoteRuntimeClient(grantId);
|
|
298
|
-
console.log(`Revoked ${grantId}; closed ${result.closedConnections} active connection(s).`);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
fail("runtime clients: expected list or revoke <grant-id>");
|
|
302
|
-
}
|
|
303
|
-
default:
|
|
304
|
-
fail(USAGE);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
async function browserCommand(args) {
|
|
308
|
-
let parsed;
|
|
309
|
-
try {
|
|
310
|
-
parsed = parseBrowserCliArgs(args);
|
|
311
|
-
}
|
|
312
|
-
catch (error) {
|
|
313
|
-
fail(error instanceof Error ? error.message : String(error));
|
|
314
|
-
}
|
|
315
|
-
const sub = parsed.subcommand;
|
|
316
|
-
const json = parsed.json;
|
|
317
|
-
if (sub === "install" || sub === "update") {
|
|
318
|
-
const version = parsed.version;
|
|
319
|
-
const channelValue = parsed.channel;
|
|
320
|
-
if (version && channelValue) {
|
|
321
|
-
fail("browser install: choose either --version or --channel");
|
|
322
|
-
}
|
|
323
|
-
if (sub === "update" && version) {
|
|
324
|
-
fail("browser update: use --channel, or browser install --version for a pinned build");
|
|
325
|
-
}
|
|
326
|
-
const selector = version
|
|
327
|
-
? { kind: "version", version }
|
|
328
|
-
: { kind: "channel", channel: browserReleaseChannel(channelValue) };
|
|
329
|
-
const resolved = await resolveChromeForTestingRelease(selector);
|
|
330
|
-
const installed = await createChromeForTestingArtifactStore().installResolved(resolved, {
|
|
331
|
-
...(json ? {} : { onProgress: (message) => console.log(message) }),
|
|
332
|
-
});
|
|
333
|
-
if (json)
|
|
334
|
-
console.log(JSON.stringify({ resolved, installed }, null, 2));
|
|
335
|
-
else
|
|
336
|
-
console.log(`Active Browser engine: Chrome for Testing ${installed.version}.`);
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
if (sub === "version") {
|
|
340
|
-
const installed = createChromeForTestingArtifactStore().readActive();
|
|
341
|
-
if (json)
|
|
342
|
-
console.log(JSON.stringify({ installed: installed ?? null }, null, 2));
|
|
343
|
-
else if (installed) {
|
|
344
|
-
console.log(`Chrome for Testing ${installed.version} · ${installed.hostPlatform} · ${installed.sha256}`);
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
console.log("No managed Chrome for Testing build is installed.");
|
|
348
|
-
}
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
if (sub === "clean") {
|
|
352
|
-
const result = createChromeForTestingArtifactStore().pruneBuilds();
|
|
353
|
-
if (json)
|
|
354
|
-
console.log(JSON.stringify(result, null, 2));
|
|
355
|
-
else if (result.removedBuilds.length === 0) {
|
|
356
|
-
console.log("No inactive Chrome for Testing builds were eligible for removal.");
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
console.log(`Removed ${result.removedBuilds.length} inactive Chrome for Testing build(s).`);
|
|
360
|
-
}
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
if (sub === "endpoint") {
|
|
364
|
-
const target = await resolveBrowserTarget(parsed);
|
|
365
|
-
if (parsed.ensure) {
|
|
366
|
-
await callBrowserRuntime(target, "browser.open", { sessionId: target.sessionId });
|
|
367
|
-
}
|
|
368
|
-
const descriptor = await getResidentRuntimeLocalBrowserEndpoint({
|
|
369
|
-
...(target.credential ? {} : { sessionId: target.sessionId }),
|
|
370
|
-
});
|
|
371
|
-
console.log(json ? JSON.stringify(descriptor, null, 2) : descriptor.endpoint);
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
const target = await resolveBrowserTarget(parsed);
|
|
375
|
-
const sessionId = target.sessionId;
|
|
376
|
-
if (sub === "open") {
|
|
377
|
-
const state = await callBrowserRuntime(target, "browser.open", {
|
|
378
|
-
sessionId,
|
|
379
|
-
...(parsed.url ? { url: parsed.url } : {}),
|
|
380
|
-
});
|
|
381
|
-
printBrowserState(state, json);
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
const state = await callBrowserRuntime(target, "browser.state.get", { sessionId });
|
|
385
|
-
if (sub === "status") {
|
|
386
|
-
printBrowserState(state, json);
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
if (sub === "pages") {
|
|
390
|
-
if (json)
|
|
391
|
-
console.log(JSON.stringify({ pages: state?.pages ?? [] }, null, 2));
|
|
392
|
-
else
|
|
393
|
-
printBrowserPages(state);
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
if (!state) {
|
|
397
|
-
if (json)
|
|
398
|
-
console.log(JSON.stringify({ closed: false, browser: null }, null, 2));
|
|
399
|
-
else
|
|
400
|
-
console.log(`No Browser is open for Session ${sessionId}.`);
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
const result = await callBrowserRuntime(target, "browser.close", {
|
|
404
|
-
sessionId,
|
|
405
|
-
browserGeneration: state.browserGeneration,
|
|
406
|
-
});
|
|
407
|
-
console.log(json
|
|
408
|
-
? JSON.stringify(result, null, 2)
|
|
409
|
-
: `Closed Browser generation ${result.browserGeneration} for Session ${sessionId}.`);
|
|
410
|
-
}
|
|
411
|
-
function browserReleaseChannel(value) {
|
|
412
|
-
const normalized = value === undefined
|
|
413
|
-
? "Stable"
|
|
414
|
-
: `${value.slice(0, 1).toUpperCase()}${value.slice(1).toLowerCase()}`;
|
|
415
|
-
if (normalized !== "Stable" &&
|
|
416
|
-
normalized !== "Beta" &&
|
|
417
|
-
normalized !== "Dev" &&
|
|
418
|
-
normalized !== "Canary") {
|
|
419
|
-
fail("browser: --channel must be stable, beta, dev, or canary");
|
|
420
|
-
}
|
|
421
|
-
return normalized;
|
|
422
|
-
}
|
|
423
|
-
async function resolveBrowserTarget(args) {
|
|
424
|
-
const credential = await readOptionalManagedRuntimeBrowserCredential();
|
|
425
|
-
try {
|
|
426
|
-
return resolveBrowserCliTarget(args, credential);
|
|
427
|
-
}
|
|
428
|
-
catch (error) {
|
|
429
|
-
fail(error instanceof Error ? error.message : String(error));
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
async function callBrowserRuntime(target, method, params) {
|
|
433
|
-
if (target.credential) {
|
|
434
|
-
return callManagedRuntimeBrowser(target.credential, method, params);
|
|
435
|
-
}
|
|
436
|
-
return callResidentRuntime(target.runtimeSelector, method, params);
|
|
437
|
-
}
|
|
438
|
-
function printBrowserState(state, json) {
|
|
439
|
-
if (json) {
|
|
440
|
-
console.log(JSON.stringify({ browser: state }, null, 2));
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
if (!state) {
|
|
444
|
-
console.log("No Browser is open for this Session.");
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
console.log(`Browser ${state.status} · ${state.executionBackend} · generation ${state.browserGeneration}`);
|
|
448
|
-
printBrowserPages(state);
|
|
449
|
-
}
|
|
450
|
-
function printBrowserPages(state) {
|
|
451
|
-
if (!state || state.pages.length === 0) {
|
|
452
|
-
console.log(" (no Pages)");
|
|
453
|
-
return;
|
|
454
|
-
}
|
|
455
|
-
for (const page of state.pages) {
|
|
456
|
-
const marker = page.pageId === state.activePageId ? "*" : " ";
|
|
457
|
-
const title = page.title ? ` ${page.title}` : "";
|
|
458
|
-
console.log(`${marker} ${page.pageId} ${page.url}${title}`);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
function optionValue(args, option) {
|
|
462
|
-
const index = args.indexOf(option);
|
|
463
|
-
if (index < 0)
|
|
464
|
-
return undefined;
|
|
465
|
-
const value = args[index + 1];
|
|
466
|
-
if (!value || value.startsWith("--"))
|
|
467
|
-
fail(`${option}: missing value`);
|
|
468
|
-
return value;
|
|
469
|
-
}
|
|
470
|
-
async function readStdinBounded(maxBytes) {
|
|
471
|
-
const chunks = [];
|
|
472
|
-
let bytes = 0;
|
|
473
|
-
for await (const chunk of process.stdin) {
|
|
474
|
-
const value = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
475
|
-
bytes += value.byteLength;
|
|
476
|
-
if (bytes > maxBytes)
|
|
477
|
-
fail(`stdin exceeds ${maxBytes} bytes`);
|
|
478
|
-
chunks.push(value);
|
|
479
|
-
}
|
|
480
|
-
return Buffer.concat(chunks, bytes).toString("utf8");
|
|
481
|
-
}
|
|
482
|
-
async function main() {
|
|
483
|
-
const [command, sub, arg] = process.argv.slice(2);
|
|
484
|
-
switch (command) {
|
|
485
|
-
case "setup":
|
|
486
|
-
process.exit(await runSetup());
|
|
487
|
-
break;
|
|
488
|
-
case "doctor":
|
|
489
|
-
process.exit(await runDoctor());
|
|
490
|
-
break;
|
|
491
|
-
case "update": {
|
|
492
|
-
const rest = process.argv.slice(3);
|
|
493
|
-
const version = rest.find((a) => !a.startsWith("--"));
|
|
494
|
-
process.exit(await runUpdate({
|
|
495
|
-
check: rest.includes("--check"),
|
|
496
|
-
json: rest.includes("--json"),
|
|
497
|
-
version,
|
|
498
|
-
}));
|
|
499
|
-
break;
|
|
500
|
-
}
|
|
501
|
-
case "start":
|
|
502
|
-
process.exit(startDaemon({ force: false }));
|
|
503
|
-
break;
|
|
504
|
-
case "restart":
|
|
505
|
-
process.exit(startDaemon({ force: true }));
|
|
506
|
-
break;
|
|
507
|
-
case "stop":
|
|
508
|
-
process.exit(stopDaemon());
|
|
509
|
-
break;
|
|
510
|
-
case "status":
|
|
511
|
-
process.exit(statusDaemon());
|
|
512
|
-
break;
|
|
513
|
-
case "logs":
|
|
514
|
-
streamLogs();
|
|
515
|
-
break;
|
|
516
|
-
case "plugin":
|
|
517
|
-
process.exitCode = await runModernCli(["plugin", ...process.argv.slice(3)]);
|
|
518
|
-
break;
|
|
519
|
-
case "market":
|
|
520
|
-
process.exitCode = await runModernCli(["market", ...process.argv.slice(3)]);
|
|
521
|
-
break;
|
|
522
|
-
case "agent":
|
|
523
|
-
await agentCommand(sub, arg);
|
|
524
|
-
break;
|
|
525
|
-
case "cleanup":
|
|
526
|
-
await cleanupCommand(sub);
|
|
527
|
-
break;
|
|
528
|
-
case "emulator":
|
|
529
|
-
emulatorPassthrough(process.argv.slice(3));
|
|
530
|
-
break;
|
|
531
|
-
case "runtime":
|
|
532
|
-
await runtimeCommand(process.argv.slice(3));
|
|
533
|
-
break;
|
|
534
|
-
case "browser":
|
|
535
|
-
await browserCommand(process.argv.slice(3));
|
|
536
|
-
break;
|
|
537
|
-
case undefined:
|
|
538
|
-
case "help":
|
|
539
|
-
case "-h":
|
|
540
|
-
case "--help":
|
|
541
|
-
console.log(USAGE);
|
|
542
|
-
break;
|
|
543
|
-
default:
|
|
544
|
-
fail(`Unknown command: ${command}\n\n${USAGE}`);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
main().catch((err) => {
|
|
548
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
549
|
-
process.exit(1);
|
|
550
|
-
});
|
package/dist/control-client.d.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { type DaemonStatus } from "@rynx-ai/protocol/remote-runtime";
|
|
2
|
-
import { type DaemonChromeInspectionConfigureInput, type DaemonChromeInspectionStatus, type DaemonShutdownIfIdleResult } from "@rynx-ai/protocol/control";
|
|
3
|
-
import { type RemoteRuntimeRpcMethod, type RemoteRuntimeRpcParams, type RemoteRuntimeRpcResultFor } from "@rynx-ai/protocol/remote-runtime-rpc";
|
|
4
|
-
import { type PairingOffer } from "@rynx-ai/protocol/direct-runtime";
|
|
5
|
-
import { type RuntimeBrowserBootstrapCredential, type RuntimeBrowserEndpointDescriptor } from "@rynx-ai/protocol/runtime-browser-bootstrap";
|
|
6
|
-
export { connectResidentDesktopBrowserHost, type ResidentDesktopBrowserHostConnection, type ResidentDesktopBrowserHostCommandRequest, type ResidentDesktopBrowserHostConnectOptions, type ResidentDesktopBrowserHostFailure, } from "./desktop-browser-host-client.js";
|
|
7
|
-
export interface ResidentDaemon {
|
|
8
|
-
origin: string;
|
|
9
|
-
}
|
|
10
|
-
export interface ResidentDaemonIdentity {
|
|
11
|
-
installationId: string;
|
|
12
|
-
algorithm: "Ed25519";
|
|
13
|
-
publicKey: string;
|
|
14
|
-
}
|
|
15
|
-
export interface ResidentPluginCommandResult {
|
|
16
|
-
code: number;
|
|
17
|
-
stdout: string;
|
|
18
|
-
stderr: string;
|
|
19
|
-
truncated: boolean;
|
|
20
|
-
}
|
|
21
|
-
export interface ResidentRemoteRuntimeClientGrant {
|
|
22
|
-
grantId: string;
|
|
23
|
-
clientId: string;
|
|
24
|
-
clientLabel: string | null;
|
|
25
|
-
clientKeyFingerprint: string;
|
|
26
|
-
authorities: string[];
|
|
27
|
-
createdAt: string;
|
|
28
|
-
revokedAt: string | null;
|
|
29
|
-
lastUsedAt: string | null;
|
|
30
|
-
}
|
|
31
|
-
export interface ResidentRuntimeTargetView {
|
|
32
|
-
selector: string;
|
|
33
|
-
daemonId: string;
|
|
34
|
-
displayName: string;
|
|
35
|
-
binding: "local" | "direct";
|
|
36
|
-
endpoint?: string;
|
|
37
|
-
identityKeyFingerprint?: string;
|
|
38
|
-
createdAt?: string;
|
|
39
|
-
}
|
|
40
|
-
export interface ResidentRuntimeTargetTestResult {
|
|
41
|
-
target: ResidentRuntimeTargetView;
|
|
42
|
-
status: DaemonStatus;
|
|
43
|
-
}
|
|
44
|
-
export interface InvokeResidentPluginCommandOptions {
|
|
45
|
-
stdin?: string;
|
|
46
|
-
signal?: AbortSignal;
|
|
47
|
-
}
|
|
48
|
-
export type ResidentRuntimeCallErrorCode = "invalid_target" | "invalid_request" | "not_found" | "conflict" | "failed_precondition" | "method_not_found" | "deadline_exceeded" | "unreachable" | "tls_error" | "identity_mismatch" | "incompatible" | "authentication_failed" | "protocol_error" | "operation_failed" | "outcome_unknown" | "cancelled" | "unauthorized" | "closed" | "internal" | "internal_error";
|
|
49
|
-
export type ResidentRuntimeCallOutcome = "not_started" | "unknown";
|
|
50
|
-
/** Stable error returned by the resident daemon's typed Runtime gateway. */
|
|
51
|
-
export declare class ResidentRuntimeCallError extends Error {
|
|
52
|
-
readonly code: ResidentRuntimeCallErrorCode;
|
|
53
|
-
readonly status?: number | undefined;
|
|
54
|
-
readonly outcome?: ResidentRuntimeCallOutcome;
|
|
55
|
-
constructor(code: ResidentRuntimeCallErrorCode, message: string, status?: number | undefined, options?: ErrorOptions & {
|
|
56
|
-
outcome?: ResidentRuntimeCallOutcome;
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
/** Connect to the one resident daemon, starting its supervisor when absent. */
|
|
60
|
-
export declare function ensureResidentDaemon(): Promise<ResidentDaemon>;
|
|
61
|
-
/** Read the stable public identity of the single resident daemon. */
|
|
62
|
-
export declare function getResidentDaemonIdentity(): Promise<ResidentDaemonIdentity>;
|
|
63
|
-
/** Read the transport-independent status of the resident daemon process. */
|
|
64
|
-
export declare function getResidentDaemonRuntimeStatus(): Promise<DaemonStatus>;
|
|
65
|
-
/**
|
|
66
|
-
* Ask the resident daemon to perform one final activity check and stop only
|
|
67
|
-
* when idle. Busy is a normal result so the caller can ask the user to resolve
|
|
68
|
-
* the listed work and explicitly retry.
|
|
69
|
-
*/
|
|
70
|
-
export declare function shutdownResidentDaemonIfIdle(): Promise<DaemonShutdownIfIdleResult>;
|
|
71
|
-
export declare function getResidentChromeInspectionStatus(): Promise<DaemonChromeInspectionStatus>;
|
|
72
|
-
export declare function configureResidentChromeInspection(input: DaemonChromeInspectionConfigureInput): Promise<DaemonChromeInspectionStatus>;
|
|
73
|
-
/** Create one pairing offer on the resident daemon for a selected reachable route. */
|
|
74
|
-
export declare function createResidentRemoteRuntimePairingOffer(input?: {
|
|
75
|
-
clientLabel?: string;
|
|
76
|
-
address?: string;
|
|
77
|
-
}): Promise<PairingOffer>;
|
|
78
|
-
/** List redacted client grants accepted by the resident daemon. */
|
|
79
|
-
export declare function listResidentRemoteRuntimeClients(): Promise<ResidentRemoteRuntimeClientGrant[]>;
|
|
80
|
-
/** Revoke one resident-daemon client grant and close its active channels. */
|
|
81
|
-
export declare function revokeResidentRemoteRuntimeClient(grantId: string): Promise<{
|
|
82
|
-
revoked: true;
|
|
83
|
-
closedConnections: number;
|
|
84
|
-
}>;
|
|
85
|
-
/** List local and paired Runtime targets through the resident daemon BFF. */
|
|
86
|
-
export declare function listResidentRuntimeTargets(): Promise<ResidentRuntimeTargetView[]>;
|
|
87
|
-
/** Pair a target; the offer remains inside the loopback management request. */
|
|
88
|
-
export declare function pairResidentRuntimeTarget(offer: unknown, displayName?: string): Promise<ResidentRuntimeTargetTestResult>;
|
|
89
|
-
export declare function testResidentRuntimeTarget(selector: string): Promise<ResidentRuntimeTargetTestResult>;
|
|
90
|
-
export declare function forgetResidentRuntimeTarget(daemonId: string): Promise<{
|
|
91
|
-
forgotten: true;
|
|
92
|
-
}>;
|
|
93
|
-
/**
|
|
94
|
-
* Invoke one typed Runtime method through the single resident daemon.
|
|
95
|
-
*
|
|
96
|
-
* The short-lived CLI process never reads Direct credentials or opens a
|
|
97
|
-
* remote socket. The resident daemon owns target resolution, Local/Direct
|
|
98
|
-
* connection reuse, authorization and no-retry outcome semantics.
|
|
99
|
-
*/
|
|
100
|
-
export declare function callResidentRuntime<M extends RemoteRuntimeRpcMethod>(selectorInput: string, method: M, params: RemoteRuntimeRpcParams<M>, options?: {
|
|
101
|
-
signal?: AbortSignal;
|
|
102
|
-
}): Promise<RemoteRuntimeRpcResultFor<M>>;
|
|
103
|
-
/** Read the current managed Session credential without exposing it in output. */
|
|
104
|
-
export declare function readManagedRuntimeBrowserCredential(env?: NodeJS.ProcessEnv): Promise<RuntimeBrowserBootstrapCredential>;
|
|
105
|
-
/** Return undefined only when the process has no managed Session context at all. */
|
|
106
|
-
export declare function readOptionalManagedRuntimeBrowserCredential(env?: NodeJS.ProcessEnv): Promise<RuntimeBrowserBootstrapCredential | undefined>;
|
|
107
|
-
/**
|
|
108
|
-
* Invoke Browser control for the caller's own managed Session. Unlike the
|
|
109
|
-
* operator Runtime gateway, this path never reads or sends daemon management
|
|
110
|
-
* authority and cannot select a remote Runtime or another Session.
|
|
111
|
-
*/
|
|
112
|
-
export declare function callManagedRuntimeBrowser<M extends RemoteRuntimeRpcMethod>(credential: RuntimeBrowserBootstrapCredential, method: M, params: RemoteRuntimeRpcParams<M>, options?: {
|
|
113
|
-
signal?: AbortSignal;
|
|
114
|
-
}): Promise<RemoteRuntimeRpcResultFor<M>>;
|
|
115
|
-
/** Resolve native CDP for the caller's own Session on this Runtime only. */
|
|
116
|
-
export declare function getResidentRuntimeLocalBrowserEndpoint(options?: {
|
|
117
|
-
env?: NodeJS.ProcessEnv;
|
|
118
|
-
sessionId?: string;
|
|
119
|
-
signal?: AbortSignal;
|
|
120
|
-
}): Promise<RuntimeBrowserEndpointDescriptor>;
|
|
121
|
-
/** Invoke one command declared by an installed plugin through the resident daemon. */
|
|
122
|
-
export declare function invokeResidentPluginCommand(pluginId: string, args: readonly string[], options?: InvokeResidentPluginCommandOptions): Promise<ResidentPluginCommandResult>;
|