
























@@ -297,4 +297,69 @@ describe("skills-remote", () => {
297297fs.rmSync(workspaceDir, { recursive: true, force: true });
298298}
299299});
300+301+it("records bins from system.which object-map responses", async () => {
302+await resetSkillsRefreshForTest();
303+const workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-remote-skills-"));
304+const nodeId = `node-${randomUUID()}`;
305+const bin = `bin-${randomUUID()}`;
306+try {
307+fs.mkdirSync(path.join(workspaceDir, "remote-skill"), { recursive: true });
308+fs.writeFileSync(
309+path.join(workspaceDir, "remote-skill", "SKILL.md"),
310+[
311+"---",
312+"name: remote-skill",
313+"description: Needs a remote bin",
314+`metadata: { "openclaw": { "os": ["darwin"], "requires": { "bins": ["${bin}"] } } }`,
315+"---",
316+"# Remote Skill",
317+"",
318+].join("\n"),
319+);
320+const cfg = {
321+agents: {
322+defaults: {
323+workspace: workspaceDir,
324+},
325+},
326+} satisfies OpenClawConfig;
327+const invokeCalls: string[] = [];
328+setSkillsRemoteRegistry({
329+listConnected: () => [],
330+get: () => undefined,
331+invoke: async (params: { command: string }) => {
332+invokeCalls.push(params.command);
333+return {
334+ok: true,
335+payload: { bins: { [bin]: `/opt/homebrew/bin/${bin}`, missing: "" } },
336+payloadJSON: JSON.stringify({ bins: { [bin]: `/opt/homebrew/bin/${bin}` } }),
337+};
338+},
339+} as unknown as NodeRegistry);
340+recordRemoteNodeInfo({
341+ nodeId,
342+displayName: "Remote Mac",
343+platform: "darwin",
344+commands: ["system.run", "system.which"],
345+});
346+const before = getSkillsSnapshotVersion(workspaceDir);
347+348+await refreshRemoteNodeBins({
349+ nodeId,
350+platform: "darwin",
351+commands: ["system.run", "system.which"],
352+ cfg,
353+timeoutMs: 10,
354+});
355+356+expect(invokeCalls).toEqual(["system.which"]);
357+expect(getRemoteSkillEligibility()?.hasBin(bin)).toBe(true);
358+expect(getRemoteSkillEligibility()?.hasBin("missing")).toBe(false);
359+expect(getSkillsSnapshotVersion(workspaceDir)).toBeGreaterThan(before);
360+} finally {
361+removeRemoteNodeInfo(nodeId);
362+fs.rmSync(workspaceDir, { recursive: true, force: true });
363+}
364+});
300365});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。