@rynx-ai/daemon 0.1.11-beta.3 → 0.1.11-beta.30
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 +24 -18
- package/bundled-plugins/plugins/lark/dist/lark.js +18 -12
- package/bundled-plugins/plugins/lark/dist/runtime.js +6046 -6018
- package/bundled-plugins/plugins/lark/dist/settings.js +6006 -5987
- 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.js +4 -1
- package/dist/chrome-for-testing-runtime.js +4 -3
- package/dist/chrome-for-testing-store.js +29 -7
- 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.js +25 -14
- package/dist/db.d.ts +2 -2
- package/dist/db.js +133 -21
- package/dist/lifecycle.d.ts +1 -0
- package/dist/lifecycle.js +3 -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 +31 -9
- package/dist/plugin-host-rpc.js +428 -80
- package/dist/plugin-installer.js +3 -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.js +0 -4
- package/dist/remote-runtime-access-store.d.ts +2 -2
- package/dist/remote-runtime-access-store.js +6 -9
- package/dist/remote-runtime-connection-manager.js +1 -1
- 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.d.ts +1 -0
- package/dist/session-fork-store.js +82 -28
- package/dist/session-launch-operations.js +6 -5
- package/dist/session-log-store.d.ts +1 -0
- package/dist/session-log-store.js +19 -16
- 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.d.ts +20 -6
- package/dist/session-resource-store.js +364 -68
- package/dist/setup-service.d.ts +1 -0
- package/dist/setup-service.js +1 -0
- package/dist/skills-catalog.d.ts +11 -2
- package/dist/skills-catalog.js +317 -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 +15 -12
- package/bundled-plugins/plugins/lark/ui/assets/index-B2dhMlMU.css +0 -1
- /package/bundled-plugins/plugins/lark/ui/assets/{index-D9N-AkLX.js → index-D8Amoe6a.js} +0 -0
package/dist/daemon-server.js
CHANGED
|
@@ -17,9 +17,10 @@ import { REMOTE_RUNTIME_CORE_PROTOCOL } from "@rynx-ai/protocol/remote-runtime";
|
|
|
17
17
|
import { RUNTIME_BROWSER_INSPECT_MAX_MESSAGE_BYTES, RUNTIME_BROWSER_INSPECT_SEMANTIC_CAPABILITY, } from "@rynx-ai/protocol/runtime-browser-inspect";
|
|
18
18
|
import { RUNTIME_BROWSER_SURFACE_SEMANTIC_CAPABILITY } from "@rynx-ai/protocol/runtime-browser-surface";
|
|
19
19
|
import { RUNTIME_EMULATOR_SURFACE_SEMANTIC_CAPABILITY } from "@rynx-ai/protocol/runtime-emulator-surface";
|
|
20
|
-
import { createDaemonRuntimeHost, createDesktopFirstSessionBrowserHost, createRunnerSessionTerminalHost, createSessionRuntimeServices, DesktopBrowserHostAbsentError, DesktopBrowserHostRegistry, DirectRuntimeConnectionHub, DirectRuntimeBrowserInspectHostError, MachineSessionService, MachineSessionServiceFailure,
|
|
20
|
+
import { createDaemonRuntimeHost, createDesktopFirstSessionBrowserHost, createRunnerSessionTerminalHost, createSessionRuntimeServices, DesktopBrowserHostAbsentError, DesktopBrowserHostRegistry, DirectRuntimeConnectionHub, DirectRuntimeBrowserInspectHostError, MachineSessionService, MachineSessionServiceFailure, RemoteRuntimeDispatcher, SessionBrowserService, SessionBrowserServiceError, SessionBrowserSurfaceCoordinator, SessionEmulatorService, startServer, startDirectRuntimeServer, } from "@rynx-ai/server";
|
|
21
|
+
import { authorizeSessionPortalGrant, redeemSessionPortalTicket, } from "./session-portal-grant-store.js";
|
|
21
22
|
import { APP_BROWSER_HOST_BOOTSTRAP_TYPE, AppBrowserHostSupervisor, parseAppBrowserHostLaunchConfig, } from "./app-browser-host-supervisor.js";
|
|
22
|
-
import { buildControlDeps } from "./control-deps.js";
|
|
23
|
+
import { buildControlDeps, listControlAgentModels } from "./control-deps.js";
|
|
23
24
|
import { createBrowserArtifactManagementService } from "./browser-artifact-management.js";
|
|
24
25
|
import { createDaemonBuildStatus } from "./daemon-build-status.js";
|
|
25
26
|
import { MaintenanceLeaseStore } from "./maintenance-lease.js";
|
|
@@ -49,7 +50,7 @@ import { SqliteSessionResourceStore } from "./session-resource-store.js";
|
|
|
49
50
|
import { createSessionFallbackWorkspace, discardSessionFallbackWorkspace, } from "./session-fallback-workspace.js";
|
|
50
51
|
import { SessionBrowserCapabilityStore } from "./session-browser-capability-store.js";
|
|
51
52
|
import { SqliteSessionEmulatorBindingStore } from "./session-emulator-binding-store.js";
|
|
52
|
-
import { sessionRegistry } from "./session-meta-store.js";
|
|
53
|
+
import { sessionBelongsToPlugin, sessionRegistry } from "./session-meta-store.js";
|
|
53
54
|
import { sessionPendingMessageStore } from "./session-pending-message-store.js";
|
|
54
55
|
import { RemoteRuntimeAccessStore } from "./remote-runtime-access-store.js";
|
|
55
56
|
import { DaemonRemoteRuntimeAdmin } from "./remote-runtime-admin.js";
|
|
@@ -68,13 +69,7 @@ const require = createRequire(import.meta.url);
|
|
|
68
69
|
const DAEMON_PACKAGE_VERSION = readDaemonPackageVersion();
|
|
69
70
|
async function resolveSessionExecutionSnapshot(input) {
|
|
70
71
|
return {
|
|
71
|
-
...await resolveExecutionSnapshot(
|
|
72
|
-
...input,
|
|
73
|
-
resolveDefaultModel: async (provider) => {
|
|
74
|
-
const models = await listRuntimeModels(input.config, provider);
|
|
75
|
-
return models?.data.find((candidate) => candidate.isDefault)?.model;
|
|
76
|
-
},
|
|
77
|
-
}),
|
|
72
|
+
...await resolveExecutionSnapshot(input),
|
|
78
73
|
pluginSkills: snapshotEnabledPluginSkillSources(),
|
|
79
74
|
};
|
|
80
75
|
}
|
|
@@ -280,7 +275,7 @@ export async function startRynxDaemonServer({ config, warn = defaultWarn, onShut
|
|
|
280
275
|
const directConfig = directHostingSupported
|
|
281
276
|
? await loadDirectConfig()
|
|
282
277
|
: undefined;
|
|
283
|
-
const control = buildControlDeps();
|
|
278
|
+
const control = buildControlDeps(appConfig);
|
|
284
279
|
const installationIdentity = await loadOrCreateDaemonInstallationIdentity();
|
|
285
280
|
const directEncryptionIdentity = directHostingSupported
|
|
286
281
|
? await loadOrCreateDaemonDirectRuntimeEncryptionIdentity()
|
|
@@ -304,10 +299,13 @@ export async function startRynxDaemonServer({ config, warn = defaultWarn, onShut
|
|
|
304
299
|
"semantic.session.interrupt.v1",
|
|
305
300
|
"semantic.session.agent-options.v1",
|
|
306
301
|
"semantic.session.launch-options.v2",
|
|
302
|
+
"semantic.session.execution-settings.v1",
|
|
307
303
|
"semantic.session.create.v1",
|
|
308
304
|
"semantic.session.fork.v1",
|
|
309
305
|
"semantic.session.message.v1",
|
|
310
|
-
"semantic.session.resources.
|
|
306
|
+
"semantic.session.resources.v2",
|
|
307
|
+
"semantic.session.files.v1",
|
|
308
|
+
"semantic.session.workspace-files.v1",
|
|
311
309
|
"semantic.session.message-queue.v1",
|
|
312
310
|
"semantic.session.delete.v1",
|
|
313
311
|
"semantic.session.interaction.v1",
|
|
@@ -410,7 +408,7 @@ export async function startRynxDaemonServer({ config, warn = defaultWarn, onShut
|
|
|
410
408
|
...((selection.provider || (!selection.agent && !selection.config))
|
|
411
409
|
? { provider: selection.provider ?? appConfig.DEFAULT_RUNTIME }
|
|
412
410
|
: {}),
|
|
413
|
-
...(selection.model ? { model: selection.model } : {}),
|
|
411
|
+
...(selection.model !== undefined ? { model: selection.model } : {}),
|
|
414
412
|
...(selection.reasoningEffort
|
|
415
413
|
? { reasoningEffort: selection.reasoningEffort }
|
|
416
414
|
: {}),
|
|
@@ -419,6 +417,11 @@ export async function startRynxDaemonServer({ config, warn = defaultWarn, onShut
|
|
|
419
417
|
};
|
|
420
418
|
},
|
|
421
419
|
},
|
|
420
|
+
sessionExecution: {
|
|
421
|
+
update: async (input) => {
|
|
422
|
+
await machineSessions.updateExecutionSettings(input);
|
|
423
|
+
},
|
|
424
|
+
},
|
|
422
425
|
sessionFork: (input) => machineSessions.fork(input),
|
|
423
426
|
admissionOpen,
|
|
424
427
|
admissionReserve: reserveAdmission,
|
|
@@ -446,6 +449,7 @@ export async function startRynxDaemonServer({ config, warn = defaultWarn, onShut
|
|
|
446
449
|
sessionContextProvider: browserRunnerSessionContexts,
|
|
447
450
|
admissionOpen,
|
|
448
451
|
admissionReserve: reserveAdmission,
|
|
452
|
+
materializeGeneratedImage: (input) => sessionResources.materializeGeneratedImage(input),
|
|
449
453
|
onMirrorError: (error, sessionId) => warn(`Session mirror failed for ${sessionId}: ${error instanceof Error ? error.message : String(error)}`),
|
|
450
454
|
});
|
|
451
455
|
const sessionBrowserHost = appBrowserHostSupervisor
|
|
@@ -556,14 +560,16 @@ export async function startRynxDaemonServer({ config, warn = defaultWarn, onShut
|
|
|
556
560
|
forks: sessionForks,
|
|
557
561
|
execution: {
|
|
558
562
|
runtime: sessionRuntimeServices.conversationRuntime,
|
|
559
|
-
resolve: ({ agent, provider, model, reasoningEffort, cwd }) => resolveSessionExecutionSnapshot({
|
|
563
|
+
resolve: ({ agent, provider, model, reasoningEffort, permissionPreset, cwd }) => resolveSessionExecutionSnapshot({
|
|
560
564
|
config: appConfig,
|
|
561
565
|
...(agent ? { agentName: agent } : {}),
|
|
562
566
|
...(provider ? { provider } : {}),
|
|
563
567
|
...(model ? { model } : {}),
|
|
564
568
|
...(reasoningEffort ? { reasoningEffort } : {}),
|
|
569
|
+
...(permissionPreset ? { permissionPreset } : {}),
|
|
565
570
|
cwd,
|
|
566
571
|
}),
|
|
572
|
+
listModels: (provider) => listControlAgentModels(appConfig, provider),
|
|
567
573
|
runner: sessionRuntimeServices.runnerManager,
|
|
568
574
|
},
|
|
569
575
|
workspace: {
|
|
@@ -794,6 +800,11 @@ export async function startRynxDaemonServer({ config, warn = defaultWarn, onShut
|
|
|
794
800
|
registry: desktopBrowserHosts,
|
|
795
801
|
daemonInstanceId,
|
|
796
802
|
},
|
|
803
|
+
sessionPortalAuthorization: {
|
|
804
|
+
redeem: redeemSessionPortalTicket,
|
|
805
|
+
authorize: authorizeSessionPortalGrant,
|
|
806
|
+
ownsSession: sessionBelongsToPlugin,
|
|
807
|
+
},
|
|
797
808
|
});
|
|
798
809
|
baseShutdown = server.shutdown.bind(server);
|
|
799
810
|
if (directConfig && directEncryptionIdentity) {
|
package/dist/db.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
2
|
/** Absolute path to the SQLite file (override via `RYNX_DB`, else `~/.rynx/rynx.db`). */
|
|
3
3
|
export declare function dbPath(): string;
|
|
4
4
|
/** Open (or reuse) the database at the current path, migrating + importing on first open. */
|
|
5
|
-
export declare function db():
|
|
5
|
+
export declare function db(): DatabaseSync;
|
package/dist/db.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `~/.rynx/rynx.db` — the daemon's SQLite store. Concerns kept apart:
|
|
3
|
-
* - `plugin_installations` — source-qualified manifests
|
|
3
|
+
* - `plugin_installations` — source-qualified manifests and immutable packages.
|
|
4
4
|
* - `plugin_marketplaces` — catalog registrations; catalog data is never executable.
|
|
5
5
|
* - `plugin_session_launch_operations` — durable idempotency/tombstones.
|
|
6
6
|
* - `control_links` — generic, one-use links to the local session console.
|
|
7
|
+
* - `session_portal_tickets` / `session_portal_grants` — hashed, scoped,
|
|
8
|
+
* browser Session Portal authorization.
|
|
7
9
|
* - `runtime_pairing_claims` / `runtime_client_grants` — one-use enrollment
|
|
8
10
|
* claims and the durable client identities they issue for direct runtimes.
|
|
9
11
|
* - `runtime_targets` / `runtime_direct_routes` / `runtime_pending_enrollments`
|
|
@@ -16,8 +18,9 @@
|
|
|
16
18
|
*/
|
|
17
19
|
import { chmodSync, mkdirSync } from "node:fs";
|
|
18
20
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
21
|
+
import { DatabaseSync } from "node:sqlite";
|
|
19
22
|
import { rynxHome } from "@rynx-ai/core";
|
|
20
|
-
import
|
|
23
|
+
import { transaction } from "./sqlite.js";
|
|
21
24
|
const connections = new Map();
|
|
22
25
|
/** Absolute path to the SQLite file (override via `RYNX_DB`, else `~/.rynx/rynx.db`). */
|
|
23
26
|
export function dbPath() {
|
|
@@ -34,9 +37,7 @@ export function db() {
|
|
|
34
37
|
if (cached)
|
|
35
38
|
return cached;
|
|
36
39
|
mkdirSync(dirname(path), { recursive: true });
|
|
37
|
-
const conn = new
|
|
38
|
-
conn.pragma("busy_timeout = 5000");
|
|
39
|
-
conn.pragma("foreign_keys = ON");
|
|
40
|
+
const conn = new DatabaseSync(path, { timeout: 5000, enableForeignKeyConstraints: true });
|
|
40
41
|
migrate(conn);
|
|
41
42
|
// Plugin state and daemon credentials are private.
|
|
42
43
|
try {
|
|
@@ -86,7 +87,6 @@ function migrate(conn) {
|
|
|
86
87
|
install_path TEXT NOT NULL,
|
|
87
88
|
manifest TEXT NOT NULL,
|
|
88
89
|
integrity TEXT NOT NULL,
|
|
89
|
-
capabilities TEXT NOT NULL,
|
|
90
90
|
runtime_state TEXT,
|
|
91
91
|
runtime_error TEXT,
|
|
92
92
|
UNIQUE(marketplace_id, plugin_id)
|
|
@@ -109,8 +109,9 @@ function migrate(conn) {
|
|
|
109
109
|
session_id TEXT NOT NULL,
|
|
110
110
|
client_upload_id TEXT NOT NULL,
|
|
111
111
|
upload_id TEXT NOT NULL UNIQUE,
|
|
112
|
+
kind TEXT NOT NULL DEFAULT 'image' CHECK(kind IN ('image', 'file')),
|
|
112
113
|
filename TEXT NOT NULL,
|
|
113
|
-
media_type TEXT NOT NULL
|
|
114
|
+
media_type TEXT NOT NULL,
|
|
114
115
|
byte_length INTEGER NOT NULL,
|
|
115
116
|
uploaded_bytes INTEGER NOT NULL DEFAULT 0,
|
|
116
117
|
sha256 TEXT,
|
|
@@ -141,6 +142,9 @@ function migrate(conn) {
|
|
|
141
142
|
'failed_not_started'
|
|
142
143
|
)),
|
|
143
144
|
error TEXT,
|
|
145
|
+
response_id TEXT,
|
|
146
|
+
message_item_id TEXT,
|
|
147
|
+
execution_snapshot TEXT,
|
|
144
148
|
created_at INTEGER NOT NULL,
|
|
145
149
|
updated_at INTEGER NOT NULL,
|
|
146
150
|
PRIMARY KEY(session_id, client_message_id)
|
|
@@ -245,6 +249,39 @@ function migrate(conn) {
|
|
|
245
249
|
);
|
|
246
250
|
CREATE INDEX IF NOT EXISTS idx_control_links_expires
|
|
247
251
|
ON control_links(expires_at);
|
|
252
|
+
CREATE TABLE IF NOT EXISTS session_portal_tickets (
|
|
253
|
+
ticket_hash TEXT PRIMARY KEY,
|
|
254
|
+
plugin_id TEXT NOT NULL,
|
|
255
|
+
scope TEXT NOT NULL CHECK(scope IN ('plugin_sessions', 'single_session')),
|
|
256
|
+
access TEXT NOT NULL CHECK(access IN ('read_only', 'read_write')),
|
|
257
|
+
session_id TEXT,
|
|
258
|
+
created_at TEXT NOT NULL,
|
|
259
|
+
expires_at TEXT NOT NULL,
|
|
260
|
+
used_at TEXT,
|
|
261
|
+
CHECK(
|
|
262
|
+
(scope = 'plugin_sessions' AND session_id IS NULL)
|
|
263
|
+
OR (scope = 'single_session' AND session_id IS NOT NULL)
|
|
264
|
+
)
|
|
265
|
+
);
|
|
266
|
+
CREATE INDEX IF NOT EXISTS idx_session_portal_tickets_expires
|
|
267
|
+
ON session_portal_tickets(expires_at);
|
|
268
|
+
CREATE TABLE IF NOT EXISTS session_portal_grants (
|
|
269
|
+
portal_id TEXT PRIMARY KEY,
|
|
270
|
+
secret_hash TEXT NOT NULL,
|
|
271
|
+
plugin_id TEXT NOT NULL,
|
|
272
|
+
scope TEXT NOT NULL CHECK(scope IN ('plugin_sessions', 'single_session')),
|
|
273
|
+
access TEXT NOT NULL CHECK(access IN ('read_only', 'read_write')),
|
|
274
|
+
session_id TEXT,
|
|
275
|
+
created_at TEXT NOT NULL,
|
|
276
|
+
expires_at TEXT NOT NULL,
|
|
277
|
+
revoked_at TEXT,
|
|
278
|
+
CHECK(
|
|
279
|
+
(scope = 'plugin_sessions' AND session_id IS NULL)
|
|
280
|
+
OR (scope = 'single_session' AND session_id IS NOT NULL)
|
|
281
|
+
)
|
|
282
|
+
);
|
|
283
|
+
CREATE INDEX IF NOT EXISTS idx_session_portal_grants_expires
|
|
284
|
+
ON session_portal_grants(expires_at);
|
|
248
285
|
CREATE TABLE IF NOT EXISTS runtime_pairing_claims (
|
|
249
286
|
claim_id TEXT PRIMARY KEY,
|
|
250
287
|
secret_hash TEXT NOT NULL,
|
|
@@ -308,7 +345,8 @@ function migrate(conn) {
|
|
|
308
345
|
CREATE INDEX IF NOT EXISTS idx_runtime_pending_enrollments_expires
|
|
309
346
|
ON runtime_pending_enrollments(expires_at);
|
|
310
347
|
`);
|
|
311
|
-
|
|
348
|
+
migrateSessionResourceFiles(conn);
|
|
349
|
+
migratePluginCapabilityDeclarations(conn);
|
|
312
350
|
migrateSessionSnapshots(conn);
|
|
313
351
|
// Breaking plugin-runtime cutover: remove obsolete core-owned state.
|
|
314
352
|
conn.exec(`
|
|
@@ -318,6 +356,92 @@ function migrate(conn) {
|
|
|
318
356
|
addColumnIfMissing(conn, "plugin_marketplaces", "built_in", "INTEGER NOT NULL DEFAULT 0");
|
|
319
357
|
addColumnIfMissing(conn, "sessions", "forked_from_session_id", "TEXT");
|
|
320
358
|
addColumnIfMissing(conn, "plugin_session_launch_operations", "raw_request_hash", "TEXT");
|
|
359
|
+
addColumnIfMissing(conn, "session_message_operations", "response_id", "TEXT");
|
|
360
|
+
addColumnIfMissing(conn, "session_message_operations", "message_item_id", "TEXT");
|
|
361
|
+
addColumnIfMissing(conn, "session_message_operations", "execution_snapshot", "TEXT");
|
|
362
|
+
}
|
|
363
|
+
/** Rebuild the original image-only table without losing committed resources. */
|
|
364
|
+
function migrateSessionResourceFiles(conn) {
|
|
365
|
+
const columns = conn
|
|
366
|
+
.prepare("PRAGMA table_info(session_resources)")
|
|
367
|
+
.all();
|
|
368
|
+
if (columns.some((column) => column.name === "kind"))
|
|
369
|
+
return;
|
|
370
|
+
conn.exec("PRAGMA foreign_keys = OFF");
|
|
371
|
+
try {
|
|
372
|
+
transaction(conn, () => {
|
|
373
|
+
conn.exec(`
|
|
374
|
+
ALTER TABLE session_message_operation_resources
|
|
375
|
+
RENAME TO session_message_operation_resources_image_v1;
|
|
376
|
+
ALTER TABLE session_resources RENAME TO session_resources_image_v1;
|
|
377
|
+
|
|
378
|
+
CREATE TABLE session_resources (
|
|
379
|
+
id TEXT PRIMARY KEY,
|
|
380
|
+
session_id TEXT NOT NULL,
|
|
381
|
+
client_upload_id TEXT NOT NULL,
|
|
382
|
+
upload_id TEXT NOT NULL UNIQUE,
|
|
383
|
+
kind TEXT NOT NULL DEFAULT 'image' CHECK(kind IN ('image', 'file')),
|
|
384
|
+
filename TEXT NOT NULL,
|
|
385
|
+
media_type TEXT NOT NULL,
|
|
386
|
+
byte_length INTEGER NOT NULL,
|
|
387
|
+
uploaded_bytes INTEGER NOT NULL DEFAULT 0,
|
|
388
|
+
sha256 TEXT,
|
|
389
|
+
width INTEGER,
|
|
390
|
+
height INTEGER,
|
|
391
|
+
state TEXT NOT NULL DEFAULT 'uploading'
|
|
392
|
+
CHECK(state IN ('uploading', 'staged', 'committed')),
|
|
393
|
+
message_item_id TEXT,
|
|
394
|
+
created_at INTEGER NOT NULL,
|
|
395
|
+
committed_at INTEGER,
|
|
396
|
+
UNIQUE(session_id, client_upload_id)
|
|
397
|
+
);
|
|
398
|
+
INSERT INTO session_resources (
|
|
399
|
+
id, session_id, client_upload_id, upload_id, kind, filename, media_type,
|
|
400
|
+
byte_length, uploaded_bytes, sha256, width, height, state,
|
|
401
|
+
message_item_id, created_at, committed_at
|
|
402
|
+
)
|
|
403
|
+
SELECT
|
|
404
|
+
id, session_id, client_upload_id, upload_id, 'image', filename, media_type,
|
|
405
|
+
byte_length, uploaded_bytes, sha256, width, height, state,
|
|
406
|
+
message_item_id, created_at, committed_at
|
|
407
|
+
FROM session_resources_image_v1;
|
|
408
|
+
|
|
409
|
+
CREATE TABLE session_message_operation_resources (
|
|
410
|
+
session_id TEXT NOT NULL,
|
|
411
|
+
client_message_id TEXT NOT NULL,
|
|
412
|
+
resource_id TEXT NOT NULL UNIQUE REFERENCES session_resources(id) ON DELETE CASCADE,
|
|
413
|
+
PRIMARY KEY(session_id, client_message_id, resource_id),
|
|
414
|
+
FOREIGN KEY(session_id, client_message_id)
|
|
415
|
+
REFERENCES session_message_operations(session_id, client_message_id)
|
|
416
|
+
ON DELETE CASCADE
|
|
417
|
+
);
|
|
418
|
+
INSERT INTO session_message_operation_resources
|
|
419
|
+
SELECT * FROM session_message_operation_resources_image_v1;
|
|
420
|
+
|
|
421
|
+
DROP TABLE session_message_operation_resources_image_v1;
|
|
422
|
+
DROP TABLE session_resources_image_v1;
|
|
423
|
+
CREATE INDEX idx_session_resources_session
|
|
424
|
+
ON session_resources(session_id, created_at);
|
|
425
|
+
CREATE INDEX idx_session_resources_message
|
|
426
|
+
ON session_resources(message_item_id);
|
|
427
|
+
`);
|
|
428
|
+
})();
|
|
429
|
+
}
|
|
430
|
+
finally {
|
|
431
|
+
conn.exec("PRAGMA foreign_keys = ON");
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
/** Remove the inert permission-declaration columns left by older installations. */
|
|
435
|
+
function migratePluginCapabilityDeclarations(conn) {
|
|
436
|
+
const columns = conn
|
|
437
|
+
.prepare("PRAGMA table_info(plugin_installations)")
|
|
438
|
+
.all();
|
|
439
|
+
const names = new Set(columns.map((column) => column.name));
|
|
440
|
+
for (const legacyColumn of ["capabilities", "grants"]) {
|
|
441
|
+
if (names.has(legacyColumn)) {
|
|
442
|
+
conn.exec(`ALTER TABLE plugin_installations DROP COLUMN ${legacyColumn}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
321
445
|
}
|
|
322
446
|
/**
|
|
323
447
|
* Breaking Session cutover: the previous rows contain mutable Agent/Provider
|
|
@@ -330,7 +454,7 @@ function migrateSessionSnapshots(conn) {
|
|
|
330
454
|
const names = new Set(columns.map((column) => column.name));
|
|
331
455
|
if (names.has("workspace") && names.has("execution"))
|
|
332
456
|
return;
|
|
333
|
-
|
|
457
|
+
transaction(conn, () => {
|
|
334
458
|
conn.exec(`
|
|
335
459
|
INSERT OR IGNORE INTO session_snapshot_cleanup (session_id)
|
|
336
460
|
SELECT id FROM sessions;
|
|
@@ -358,18 +482,6 @@ function migrateSessionSnapshots(conn) {
|
|
|
358
482
|
`);
|
|
359
483
|
}).immediate();
|
|
360
484
|
}
|
|
361
|
-
function migratePluginCapabilities(conn) {
|
|
362
|
-
const columns = conn
|
|
363
|
-
.prepare("PRAGMA table_info(plugin_installations)")
|
|
364
|
-
.all();
|
|
365
|
-
if (columns.some((column) => column.name === "capabilities"))
|
|
366
|
-
return;
|
|
367
|
-
if (columns.some((column) => column.name === "grants")) {
|
|
368
|
-
conn.exec("ALTER TABLE plugin_installations RENAME COLUMN grants TO capabilities");
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
conn.exec("ALTER TABLE plugin_installations ADD COLUMN capabilities TEXT NOT NULL DEFAULT '[]'");
|
|
372
|
-
}
|
|
373
485
|
/** Idempotently add a column to an existing table (no-op if already present). */
|
|
374
486
|
function addColumnIfMissing(conn, table, column, ddl) {
|
|
375
487
|
const cols = conn.prepare(`PRAGMA table_info(${table})`).all();
|
package/dist/lifecycle.d.ts
CHANGED
package/dist/lifecycle.js
CHANGED
|
@@ -11,6 +11,9 @@ export function startDaemon(options) {
|
|
|
11
11
|
RYNX_DISTRIBUTION: "standalone",
|
|
12
12
|
RYNX_PRODUCT_VERSION: options.context.productVersion,
|
|
13
13
|
RYNX_DAEMON_LIFECYCLE: "standalone",
|
|
14
|
+
// An empty value explicitly disables PATH fallback when the optional
|
|
15
|
+
// platform package is missing, while keeping the control plane runnable.
|
|
16
|
+
RYNX_TMUX_BIN: options.context.tmuxBin ?? "",
|
|
14
17
|
},
|
|
15
18
|
});
|
|
16
19
|
}
|
|
@@ -20,6 +20,7 @@ import { mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
|
|
|
20
20
|
import path from "node:path";
|
|
21
21
|
import { rynxHome } from "@rynx-ai/core";
|
|
22
22
|
import { db } from "../db.js";
|
|
23
|
+
import { transaction } from "../sqlite.js";
|
|
23
24
|
/** Mirrors the daemon runtime store's default resolution. */
|
|
24
25
|
function defaultProxyDir() {
|
|
25
26
|
return path.join(rynxHome(), ".codex-proxy");
|
|
@@ -46,9 +47,9 @@ export function cleanupLegacySessions(opts = {}) {
|
|
|
46
47
|
let deletedLogRows = 0;
|
|
47
48
|
let deletedSessions = 0;
|
|
48
49
|
let prunedStoreEntries = 0;
|
|
49
|
-
|
|
50
|
-
deletedLogRows = conn.prepare(`DELETE FROM session_items WHERE ${LEGACY_LOG}`).run().changes;
|
|
51
|
-
deletedSessions = conn.prepare(`DELETE FROM sessions WHERE ${LEGACY_META}`).run().changes;
|
|
50
|
+
transaction(conn, () => {
|
|
51
|
+
deletedLogRows = Number(conn.prepare(`DELETE FROM session_items WHERE ${LEGACY_LOG}`).run().changes);
|
|
52
|
+
deletedSessions = Number(conn.prepare(`DELETE FROM sessions WHERE ${LEGACY_META}`).run().changes);
|
|
52
53
|
})();
|
|
53
54
|
// The runtime store is daemon-owned. Plugin routing stores remain private to
|
|
54
55
|
// their plugins and are never inspected by this migration.
|
package/dist/plugin-cli.d.ts
CHANGED
|
@@ -20,6 +20,16 @@ export interface PluginCliCommandResult {
|
|
|
20
20
|
stderrTruncated: boolean;
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
+
export interface InstalledPluginListItem {
|
|
24
|
+
id: string;
|
|
25
|
+
version: string;
|
|
26
|
+
source: "local" | "git";
|
|
27
|
+
state: "enabled" | "disabled";
|
|
28
|
+
}
|
|
29
|
+
/** Read the durable installed-plugin inventory without contacting the daemon. */
|
|
30
|
+
export declare function listInstalledPlugins(): InstalledPluginListItem[];
|
|
31
|
+
/** Render manifest-declared command help without executing plugin code. */
|
|
32
|
+
export declare function installedPluginCommandUsage(pluginId: string): string;
|
|
23
33
|
/** Execute one statically declared, language-neutral plugin command. */
|
|
24
34
|
export declare function runPluginCliCommand(pluginId: string, args: readonly string[], options?: RunPluginCliOptions): Promise<PluginCliCommandResult>;
|
|
25
35
|
export declare function pluginCommandUsage(record: RunnablePluginRecord): string;
|
package/dist/plugin-cli.js
CHANGED
|
@@ -3,12 +3,29 @@ import { mkdirSync, realpathSync, statSync } from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createPluginCliInvocationLeaseId, removePluginRuntimeLease, writePluginRuntimeLease, } from "@rynx-ai/plugin-sdk";
|
|
5
5
|
import { db } from "./db.js";
|
|
6
|
+
import { transaction } from "./sqlite.js";
|
|
6
7
|
import { pluginDataDir, pluginRuntimeCacheDir } from "./plugin-installer.js";
|
|
7
8
|
import { validatePluginPackageSnapshot } from "./plugin-package.js";
|
|
8
|
-
import { getPlugin } from "./plugin-store.js";
|
|
9
|
+
import { getPlugin, listPlugins, } from "./plugin-store.js";
|
|
9
10
|
import { loadOrCreateDaemonInstallationIdentitySync } from "./installation-id.js";
|
|
10
11
|
const DEFAULT_TERMINATION_GRACE_MS = 2_000;
|
|
11
12
|
const MAX_TERMINATION_GRACE_MS = 30_000;
|
|
13
|
+
/** Read the durable installed-plugin inventory without contacting the daemon. */
|
|
14
|
+
export function listInstalledPlugins() {
|
|
15
|
+
return listPlugins().map((record) => ({
|
|
16
|
+
id: record.canonicalId,
|
|
17
|
+
version: record.version,
|
|
18
|
+
source: record.source,
|
|
19
|
+
state: record.enabled ? "enabled" : "disabled",
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
/** Render manifest-declared command help without executing plugin code. */
|
|
23
|
+
export function installedPluginCommandUsage(pluginId) {
|
|
24
|
+
const record = getPlugin(pluginId);
|
|
25
|
+
if (!record)
|
|
26
|
+
throw new Error(`plugin "${pluginId}" is not installed`);
|
|
27
|
+
return pluginCommandUsage(record);
|
|
28
|
+
}
|
|
12
29
|
/** Execute one statically declared, language-neutral plugin command. */
|
|
13
30
|
export async function runPluginCliCommand(pluginId, args, options = {}) {
|
|
14
31
|
const hostEnv = options.env ?? process.env;
|
|
@@ -74,7 +91,7 @@ export async function runPluginCliCommand(pluginId, args, options = {}) {
|
|
|
74
91
|
removePluginRuntimeLease(dataDir, leaseId);
|
|
75
92
|
};
|
|
76
93
|
try {
|
|
77
|
-
db()
|
|
94
|
+
transaction(db(), () => {
|
|
78
95
|
const record = getPlugin(pluginId);
|
|
79
96
|
if (!record)
|
|
80
97
|
throw new Error(`plugin "${pluginId}" is not installed`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { type AdmissionReservation, type AgentSpec, type AgentCapabilities, type AgentRuntimeId, type AgentSessionStore, type
|
|
2
|
-
import { type PluginAgentSummary, type
|
|
1
|
+
import { type AdmissionReservation, type AgentSpec, type AgentCapabilities, type AgentRuntimeId, type AgentSessionStore, type ResolvedExecutionSnapshot, type RuntimeCollaborationMode, type SessionRegistry, type SessionWorkspaceSnapshot, type SteerSignal } from "@rynx-ai/core";
|
|
2
|
+
import { type PluginAgentSummary, type PluginHostEvent, type PluginSessionActivitySnapshot, type PluginResolvedSessionExecution, type PluginSessionExecutionSnapshot, type PluginSessionInteractionResolveDisposition } from "@rynx-ai/plugin-sdk";
|
|
3
3
|
import type { SessionInteractionResolution } from "@rynx-ai/protocol";
|
|
4
|
+
import type { MachineSessionMessageInput, StartedMachineSessionRun } from "@rynx-ai/server";
|
|
4
5
|
import { PluginRunnerError } from "@rynx-ai/plugin-runner";
|
|
5
6
|
/** Leaves ample room for the RPC envelope below the runner's 1 MiB line cap. */
|
|
6
7
|
export declare const MAX_PLUGIN_HOST_EVENT_BYTES: number;
|
|
@@ -22,7 +23,7 @@ export interface PluginSessionLaunchSelection {
|
|
|
22
23
|
agent?: string;
|
|
23
24
|
config?: AgentSpec;
|
|
24
25
|
provider?: AgentRuntimeId;
|
|
25
|
-
model?: string;
|
|
26
|
+
model?: string | null;
|
|
26
27
|
reasoningEffort?: string;
|
|
27
28
|
title?: string;
|
|
28
29
|
}
|
|
@@ -37,7 +38,16 @@ export interface PluginHostServices {
|
|
|
37
38
|
publicKey: string;
|
|
38
39
|
sign(pluginId: string, challenge: string): string;
|
|
39
40
|
};
|
|
40
|
-
|
|
41
|
+
sessionRuns: {
|
|
42
|
+
startRun: (sessionId: string, input: string | MachineSessionMessageInput, options?: {
|
|
43
|
+
signal?: AbortSignal;
|
|
44
|
+
steer?: SteerSignal;
|
|
45
|
+
collaborationMode?: RuntimeCollaborationMode;
|
|
46
|
+
}) => Promise<StartedMachineSessionRun>;
|
|
47
|
+
};
|
|
48
|
+
sessionFiles: {
|
|
49
|
+
resolveResourcePath(sessionId: string, resourceId: string): Promise<string>;
|
|
50
|
+
};
|
|
41
51
|
capabilities: AgentCapabilities;
|
|
42
52
|
sessionStore: AgentSessionStore;
|
|
43
53
|
sessionRegistry: SessionRegistry;
|
|
@@ -45,6 +55,14 @@ export interface PluginHostServices {
|
|
|
45
55
|
sessionLaunch: {
|
|
46
56
|
resolve(input: PluginSessionLaunchSelection): Promise<PluginResolvedSessionLaunch>;
|
|
47
57
|
};
|
|
58
|
+
sessionExecution: {
|
|
59
|
+
update(input: {
|
|
60
|
+
sessionId: string;
|
|
61
|
+
model: string | null;
|
|
62
|
+
reasoningEffort: string | null;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
};
|
|
65
|
+
sessionActivity(sessionId: string): PluginSessionActivitySnapshot | Promise<PluginSessionActivitySnapshot>;
|
|
48
66
|
interruptSession?(sessionId: string): Promise<boolean>;
|
|
49
67
|
terminateSession?(sessionId: string): Promise<boolean>;
|
|
50
68
|
resolveSessionInteraction?(sessionId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<{
|
|
@@ -60,6 +78,11 @@ export interface PluginHostServices {
|
|
|
60
78
|
}>;
|
|
61
79
|
admissionOpen?: () => boolean;
|
|
62
80
|
admissionReserve?: () => AdmissionReservation | undefined;
|
|
81
|
+
sessionPortal?: {
|
|
82
|
+
scheme: "http" | "https";
|
|
83
|
+
bindHost: string;
|
|
84
|
+
port: number;
|
|
85
|
+
};
|
|
63
86
|
}
|
|
64
87
|
export interface PluginHostRpcOptions {
|
|
65
88
|
/** Manifest id returned by host.info. */
|
|
@@ -69,7 +92,6 @@ export interface PluginHostRpcOptions {
|
|
|
69
92
|
daemonInstanceId: string;
|
|
70
93
|
productVersion: string;
|
|
71
94
|
cliVersion: string;
|
|
72
|
-
capabilities: readonly PluginCapability[];
|
|
73
95
|
services: PluginHostServices;
|
|
74
96
|
/** Canonical plugin-owned root permitted for the Workspace plugin's isolated
|
|
75
97
|
* Session directory. Omitted for every other plugin. */
|
|
@@ -80,7 +102,7 @@ export interface PluginHostRpcOptions {
|
|
|
80
102
|
disposeForceAfterMs?: number;
|
|
81
103
|
}
|
|
82
104
|
/**
|
|
83
|
-
* One authenticated plugin's
|
|
105
|
+
* One authenticated plugin's Host RPC surface.
|
|
84
106
|
*
|
|
85
107
|
* This adapter is deliberately the only place that maps public string methods
|
|
86
108
|
* to trusted runtime objects. The runner receives neither this class nor its
|
|
@@ -92,7 +114,6 @@ export declare class PluginHostRpc {
|
|
|
92
114
|
private readonly daemonInstanceId;
|
|
93
115
|
private readonly productVersion;
|
|
94
116
|
private readonly cliVersion;
|
|
95
|
-
private readonly capabilities;
|
|
96
117
|
private readonly services;
|
|
97
118
|
private readonly managedWorkspaceRoot;
|
|
98
119
|
private readonly emit;
|
|
@@ -113,11 +134,11 @@ export declare class PluginHostRpc {
|
|
|
113
134
|
private runSession;
|
|
114
135
|
private runSessionAdmitted;
|
|
115
136
|
private pumpRun;
|
|
137
|
+
private projectSessionFileEvent;
|
|
116
138
|
private releaseRun;
|
|
117
|
-
private steerSession;
|
|
118
139
|
private interruptRun;
|
|
140
|
+
private sessionActivity;
|
|
119
141
|
private interruptWon;
|
|
120
|
-
private activeRun;
|
|
121
142
|
private activeRunByIdentity;
|
|
122
143
|
private getBinding;
|
|
123
144
|
private listBindings;
|
|
@@ -131,6 +152,7 @@ export declare class PluginHostRpc {
|
|
|
131
152
|
private setSessionTitle;
|
|
132
153
|
private resolveAgentExecution;
|
|
133
154
|
private issueControlLink;
|
|
155
|
+
private issueSessionPortalLink;
|
|
134
156
|
private ownedSession;
|
|
135
157
|
private isOwned;
|
|
136
158
|
}
|