





















@@ -15,8 +15,11 @@ export type NodeSession = {
1515deviceFamily?: string;
1616modelIdentifier?: string;
1717remoteIp?: string;
18+declaredCaps: string[];
1819caps: string[];
20+declaredCommands: string[];
1921commands: string[];
22+declaredPermissions?: Record<string, boolean>;
2023permissions?: Record<string, boolean>;
2124pathEnv?: string;
2225connectedAtMs: number;
@@ -138,13 +141,27 @@ export class NodeRegistry {
138141const connect = client.connect;
139142const nodeId = connect.device?.id ?? connect.client.id;
140143const caps = Array.isArray(connect.caps) ? connect.caps : [];
144+const declaredCaps = Array.isArray((connect as { declaredCaps?: string[] }).declaredCaps)
145+ ? ((connect as { declaredCaps?: string[] }).declaredCaps ?? [])
146+ : caps;
141147const commands = Array.isArray((connect as { commands?: string[] }).commands)
142148 ? ((connect as { commands?: string[] }).commands ?? [])
143149 : [];
150+const declaredCommands = Array.isArray(
151+(connect as { declaredCommands?: string[] }).declaredCommands,
152+)
153+ ? ((connect as { declaredCommands?: string[] }).declaredCommands ?? [])
154+ : commands;
144155const permissions =
145156typeof (connect as { permissions?: Record<string, boolean> }).permissions === "object"
146157 ? ((connect as { permissions?: Record<string, boolean> }).permissions ?? undefined)
147158 : undefined;
159+const declaredPermissions =
160+typeof (connect as { declaredPermissions?: Record<string, boolean> }).declaredPermissions ===
161+"object"
162+ ? ((connect as { declaredPermissions?: Record<string, boolean> }).declaredPermissions ??
163+undefined)
164+ : permissions;
148165const pathEnv =
149166typeof (connect as { pathEnv?: string }).pathEnv === "string"
150167 ? (connect as { pathEnv?: string }).pathEnv
@@ -163,8 +180,11 @@ export class NodeRegistry {
163180deviceFamily: connect.client.deviceFamily,
164181modelIdentifier: connect.client.modelIdentifier,
165182remoteIp: opts.remoteIp,
183+ declaredCaps,
166184 caps,
185+ declaredCommands,
167186 commands,
187+ declaredPermissions,
168188 permissions,
169189 pathEnv,
170190connectedAtMs: Date.now(),
@@ -208,6 +228,66 @@ export class NodeRegistry {
208228return this.nodesById.get(nodeId);
209229}
210230231+updateCommands(nodeId: string, commands: readonly string[]): NodeSession | null {
232+return this.updateSurface(nodeId, { commands });
233+}
234+235+updateSurface(
236+nodeId: string,
237+surface: {
238+caps?: readonly string[];
239+commands: readonly string[];
240+permissions?: Record<string, boolean> | undefined;
241+},
242+): NodeSession | null {
243+const node = this.nodesById.get(nodeId);
244+if (!node) {
245+return null;
246+}
247+248+const declaredCommands = new Set(node.declaredCommands);
249+const nextCommands = surface.commands.filter((command) => declaredCommands.has(command));
250+node.commands = nextCommands;
251+(node.client.connect as { commands?: string[] }).commands = nextCommands;
252+253+if ("caps" in surface) {
254+const declaredCaps = new Set(node.declaredCaps);
255+const nextCaps = (surface.caps ?? []).filter((capability) => declaredCaps.has(capability));
256+node.caps = nextCaps;
257+(node.client.connect as { caps?: string[] }).caps = nextCaps;
258+}
259+260+if ("permissions" in surface) {
261+if (surface.permissions === undefined) {
262+node.permissions = undefined;
263+(node.client.connect as { permissions?: Record<string, boolean> }).permissions = undefined;
264+return node;
265+}
266+const declared = node.declaredPermissions ?? {};
267+const nextEntries: Array<[string, boolean]> = [];
268+for (const [key, declaredValue] of Object.entries(declared)) {
269+if (!declaredValue) {
270+nextEntries.push([key, false]);
271+continue;
272+}
273+const approvedValue = surface.permissions?.[key];
274+if (approvedValue === true) {
275+nextEntries.push([key, true]);
276+continue;
277+}
278+if (approvedValue === false) {
279+nextEntries.push([key, false]);
280+}
281+}
282+const nextPermissions = nextEntries.length > 0 ? Object.fromEntries(nextEntries) : undefined;
283+node.permissions = nextPermissions;
284+(node.client.connect as { permissions?: Record<string, boolean> }).permissions =
285+nextPermissions;
286+}
287+288+return node;
289+}
290+211291async invoke(params: {
212292nodeId: string;
213293command: string;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。