Skip to content

Commit 3e7cd9e

Browse files
Shawclaude
andcommitted
fix(plugin-phone): import registerAppShellPage via subpath + parallel worker-runtime / remote-plugin-bridge fixes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f3d5fe1 commit 3e7cd9e

19 files changed

Lines changed: 864 additions & 298 deletions

File tree

bun.lock

Lines changed: 358 additions & 214 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/agent/src/services/remote-plugin-bridge.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ export class RemotePluginBridge {
180180
);
181181
}
182182

183-
const events = descriptor.events as
183+
const events = descriptor.events as unknown as
184184
| Record<string, RemoteFunctionRef[]>
185185
| undefined;
186186
if (events) {
@@ -192,7 +192,7 @@ export class RemotePluginBridge {
192192
plugin.events = eventMap;
193193
}
194194

195-
const models = descriptor.models as
195+
const models = descriptor.models as unknown as
196196
| Record<string, RemoteFunctionRef>
197197
| undefined;
198198
if (models) {
@@ -209,7 +209,7 @@ export class RemotePluginBridge {
209209
// Services: opt-in via `static rpcMethods`. The descriptor carries
210210
// one entry per service with the methods list and per-method rpc
211211
// ids; we synthesise a ServiceClass with dynamic methods.
212-
const services = descriptor.services as
212+
const services = descriptor.services as unknown as
213213
| Array<
214214
JsonObject & {
215215
serviceType: string;
@@ -219,13 +219,15 @@ export class RemotePluginBridge {
219219
>
220220
| undefined;
221221
if (services?.length) {
222-
plugin.services = services.map((svc) => this.makeServiceClassStub(svc));
222+
plugin.services = services.map((svc) =>
223+
this.makeServiceClassStub(svc),
224+
) as Plugin["services"];
223225
}
224226

225227
// Routes: the agent's existing plugin-route lifecycle will pick
226228
// these up. Each routeHandler is wrapped to forward
227229
// RouteHandlerContext via worker-rpc and return RouteHandlerResult.
228-
const routes = descriptor.routes as
230+
const routes = descriptor.routes as unknown as
229231
| Array<JsonObject & { path: string; routeHandler?: RemoteFunctionRef }>
230232
| undefined;
231233
if (routes?.length) {
@@ -237,12 +239,13 @@ export class RemotePluginBridge {
237239
// Views/widgets/componentTypes are pure JSON metadata; pass them
238240
// through unchanged so the existing view registry serves the
239241
// remote plugin's bundle the same way it does direct plugins'.
240-
if (descriptor.views) plugin.views = descriptor.views as Plugin["views"];
242+
if (descriptor.views)
243+
plugin.views = descriptor.views as unknown as Plugin["views"];
241244
if (descriptor.widgets)
242-
plugin.widgets = descriptor.widgets as Plugin["widgets"];
245+
plugin.widgets = descriptor.widgets as unknown as Plugin["widgets"];
243246
if (descriptor.componentTypes) {
244247
plugin.componentTypes =
245-
descriptor.componentTypes as Plugin["componentTypes"];
248+
descriptor.componentTypes as unknown as Plugin["componentTypes"];
246249
}
247250

248251
return plugin;
@@ -254,8 +257,11 @@ export class RemotePluginBridge {
254257
const name = descriptor.name;
255258
const similes = (descriptor.similes as string[] | undefined) ?? [];
256259
const description = String(descriptor.description ?? "");
257-
const examples = (descriptor.examples as Action["examples"]) ?? [];
258-
const validateRef = descriptor.validate as RemoteFunctionRef | undefined;
260+
const examples =
261+
(descriptor.examples as unknown as Action["examples"]) ?? [];
262+
const validateRef = descriptor.validate as unknown as
263+
| RemoteFunctionRef
264+
| undefined;
259265

260266
const handler: Action["handler"] = async (
261267
_runtime,
@@ -294,16 +300,16 @@ export class RemotePluginBridge {
294300
);
295301
return Boolean(result);
296302
}
297-
: undefined;
303+
: async () => true;
298304

299305
const action: Action = {
300306
name,
301307
similes,
302308
description,
303309
examples,
304310
handler,
311+
validate,
305312
};
306-
if (validate) action.validate = validate;
307313
return action;
308314
}
309315

@@ -580,7 +586,7 @@ export class RemotePluginBridge {
580586
const payload = args.payload as JsonValue;
581587
await this.runtime.emitEvent(
582588
eventName as Parameters<IAgentRuntime["emitEvent"]>[0],
583-
payload as Parameters<IAgentRuntime["emitEvent"]>[1],
589+
payload as unknown as Parameters<IAgentRuntime["emitEvent"]>[1],
584590
);
585591
return null;
586592
}

packages/app/test/ui-smoke/apps-session-route-cases.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,16 @@ export const DIRECT_ROUTE_CASES: readonly DirectRouteCase[] = [
107107
selector: '[data-testid="tasks-view"]',
108108
timeoutMs: 90_000,
109109
},
110+
{
111+
name: "hearwear app window",
112+
path: "/apps/hearwear",
113+
readyChecks: [{ text: "Facewear" }, { text: "No devices connected" }],
114+
timeoutMs: 90_000,
115+
},
116+
{
117+
name: "smartglasses app window",
118+
path: "/apps/smartglasses",
119+
readyChecks: [{ text: "Smartglasses" }, { text: "Connect Headset" }],
120+
timeoutMs: 90_000,
121+
},
110122
];

packages/app/test/ui-smoke/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const SETTINGS_SECTION_IDS_BY_LABEL = new Map<string, string>([
7171
["Voice", "voice"],
7272
["Capabilities", "capabilities"],
7373
["Apps", "apps"],
74-
["Carrots", "carrots"],
74+
["Carrots", "remote-plugins"],
7575
["Connectors", "connectors"],
7676
["App Permissions", "app-permissions"],
7777
["Wallet & RPC", "wallet-rpc"],

packages/plugin-host-shim/src/web.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*/
1414

1515
import type { JsonValue } from "@elizaos/plugin-remote-manifest";
16-
import { installHostShim, type PluginHostShim } from "./index.ts";
16+
import { installHostShim, type PluginHostShim } from "./index";
1717

1818
interface ParentRequest {
1919
kind: "elizaos.shim.request";

packages/plugin-remote-manifest/src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,15 @@ export type {
5959
HostRequestMessage,
6060
HostRequestMethod,
6161
HostResponseMessage,
62+
HostRpcMessage,
63+
HostRpcResultMessage,
6264
JsonArray,
6365
JsonObject,
6466
JsonPrimitive,
6567
JsonValue,
6668
LegacyRemotePluginPermission,
69+
PluginSurfaceKind,
70+
RemoteFunctionRef,
6771
RemotePluginDependencyMap,
6872
RemotePluginInstallRecord,
6973
RemotePluginInstallSource,
@@ -82,11 +86,18 @@ export type {
8286
RemotePluginViewRPC,
8387
RemotePluginWorkerManifest,
8488
RemotePluginWorkerMessage,
89+
StreamChunkMessage,
90+
StreamEndMessage,
91+
WorkerAnnounceDynamicMessage,
92+
WorkerAnnouncePluginMessage,
8593
WorkerEventMessage,
94+
WorkerInitCompleteMessage,
8695
WorkerInitMessage,
8796
WorkerReadyMessage,
8897
WorkerRequestMessage,
8998
WorkerResponseMessage,
99+
WorkerRpcMessage,
100+
WorkerRpcResultMessage,
90101
} from "./types.js";
91102
export {
92103
BUN_PERMISSIONS,

packages/plugin-sub-agent-claude-code/src/plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* down the agent process.
2727
*/
2828

29-
import { ClaudeCodeSubAgentService } from "./sub-agent-service.ts";
29+
import { ClaudeCodeSubAgentService } from "./sub-agent-service";
3030

3131
// We intentionally use loose typing for the Plugin shape rather than
3232
// pulling in @elizaos/core (which would force a heavyweight dep tree

packages/plugin-sub-agent-claude-code/src/worker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
*/
77

88
import { bootstrap } from "@elizaos/plugin-worker-runtime";
9-
import { plugin } from "./plugin.ts";
9+
import { plugin } from "./plugin";
1010

1111
await bootstrap(plugin);

packages/plugin-worker-runtime/src/bootstrap.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* ```ts
88
* // worker.ts
99
* import { bootstrap } from "@elizaos/plugin-worker-runtime";
10-
* import { pluginFooRemote } from "./plugin.ts";
10+
* import { pluginFooRemote } from "./plugin";
1111
* bootstrap(pluginFooRemote);
1212
* ```
1313
*
@@ -28,15 +28,15 @@ import {
2828
buildAnnounceDescriptor,
2929
createHandlerRegistry,
3030
type WorkerPluginShape,
31-
} from "./descriptor.ts";
32-
import { createWorkerRpcDispatcher } from "./dispatch.ts";
31+
} from "./descriptor";
32+
import { createWorkerRpcDispatcher } from "./dispatch";
3333
import {
3434
createDefaultChannel,
3535
createRequestIdAllocator,
3636
type WorkerChannel,
37-
} from "./envelope.ts";
38-
import { toWireError } from "./error.ts";
39-
import { buildRuntimeProxyApi, RuntimeProxy } from "./runtime-proxy.ts";
37+
} from "./envelope";
38+
import { toWireError } from "./error";
39+
import { buildRuntimeProxyApi, RuntimeProxy } from "./runtime-proxy";
4040

4141
/** Options accepted by {@link bootstrap}. */
4242
export interface BootstrapOptions {

packages/plugin-worker-runtime/src/descriptor.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export function buildAnnounceDescriptor(
186186
return { rpc: true, id };
187187
};
188188

189-
const descriptor: JsonObject = {
189+
const descriptor: Record<string, JsonValue> = {
190190
name: plugin.name,
191191
mode: "remote",
192192
};
@@ -198,7 +198,7 @@ export function buildAnnounceDescriptor(
198198

199199
if (plugin.actions?.length) {
200200
descriptor.actions = plugin.actions.map((action) => {
201-
const entry: JsonObject = {
201+
const entry: Record<string, JsonValue> = {
202202
name: action.name,
203203
handler: refOf(
204204
action.handler,
@@ -222,7 +222,7 @@ export function buildAnnounceDescriptor(
222222

223223
if (plugin.providers?.length) {
224224
descriptor.providers = plugin.providers.map((provider) => {
225-
const entry: JsonObject = {
225+
const entry: Record<string, JsonValue> = {
226226
name: provider.name,
227227
get: refOf(
228228
provider.get,
@@ -239,7 +239,7 @@ export function buildAnnounceDescriptor(
239239
}
240240

241241
if (plugin.models) {
242-
const modelDescriptor: JsonObject = {};
242+
const modelDescriptor: Record<string, JsonValue> = {};
243243
for (const [modelType, fn] of Object.entries(plugin.models)) {
244244
modelDescriptor[modelType] = refOf(
245245
fn,
@@ -251,7 +251,7 @@ export function buildAnnounceDescriptor(
251251
}
252252

253253
if (plugin.events) {
254-
const eventDescriptor: JsonObject = {};
254+
const eventDescriptor: Record<string, JsonValue> = {};
255255
for (const [eventName, handlers] of Object.entries(plugin.events)) {
256256
eventDescriptor[eventName] = handlers.map(
257257
(handler, index) =>
@@ -267,7 +267,7 @@ export function buildAnnounceDescriptor(
267267

268268
if (plugin.services?.length) {
269269
descriptor.services = plugin.services.map((service) => {
270-
const entry: JsonObject = {
270+
const entry: Record<string, JsonValue> = {
271271
serviceType: service.serviceType,
272272
rpcMethods: service.rpcMethods,
273273
};
@@ -294,7 +294,7 @@ export function buildAnnounceDescriptor(
294294

295295
if (plugin.evaluators?.length) {
296296
descriptor.evaluators = plugin.evaluators.map((evaluator) => {
297-
const entry: JsonObject = {
297+
const entry: Record<string, JsonValue> = {
298298
name: evaluator.name,
299299
handler: refOf(
300300
evaluator.handler,
@@ -316,7 +316,7 @@ export function buildAnnounceDescriptor(
316316

317317
if (plugin.routes?.length) {
318318
descriptor.routes = plugin.routes.map((route) => {
319-
const entry: JsonObject = {
319+
const entry: Record<string, JsonValue> = {
320320
path: route.path,
321321
};
322322
if (route.type) entry.type = route.type;

0 commit comments

Comments
 (0)