fix(ci): restore main validation

This commit is contained in:
Peter Steinberger
2026-05-07 11:58:46 +01:00
parent 6ef7fa08af
commit 56636dfe57
7 changed files with 256 additions and 19 deletions

View File

@@ -1,13 +1,14 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { describe, expect, test, vi } from "vitest";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { WebSocket } from "ws";
import type { DeviceIdentity } from "../infra/device-identity.js";
import { loadOrCreateDeviceIdentity } from "../infra/device-identity.js";
import { approveDevicePairing, listDevicePairing } from "../infra/device-pairing.js";
import { approveNodePairing, requestNodePairing } from "../infra/node-pairing.js";
import { resolveRestartSentinelPath } from "../infra/restart-sentinel.js";
import { getActiveRuntimePluginRegistry } from "../plugins/active-runtime-registry.js";
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
import type { GatewayClient } from "./client.js";
@@ -38,6 +39,38 @@ const FAST_WAIT_OPTS = { timeout: 1_000, interval: 2 } as const;
let ws: WebSocket;
let port: number;
function installCanvasNodePolicyForTest() {
const registry = getActiveRuntimePluginRegistry();
if (!registry) {
throw new Error("active plugin registry is required for canvas node command tests");
}
if (
(registry.nodeInvokePolicies ?? []).some((entry) =>
entry.policy.commands.includes("canvas.snapshot"),
)
) {
return;
}
registry.nodeInvokePolicies ??= [];
registry.nodeInvokePolicies.push({
pluginId: "canvas",
pluginName: "Canvas",
source: "test",
rootDir: "extensions/canvas",
pluginConfig: {},
policy: {
commands: ["canvas.snapshot"],
defaultPlatforms: ["ios", "android", "macos", "windows", "unknown"],
foregroundRestrictedOnIos: true,
handle: (ctx) => ctx.invokeNode(),
},
});
}
beforeEach(() => {
installCanvasNodePolicyForTest();
});
installConnectedControlUiServerSuite((started) => {
ws = started.ws;
port = started.port;

View File

@@ -1417,5 +1417,71 @@
"type": "object"
},
"name": "web_fetch"
},
{
"description": "Control node canvases (present/hide/navigate/eval/snapshot/A2UI). Use snapshot to capture the rendered UI.",
"inputSchema": {
"properties": {
"action": {
"enum": ["present", "hide", "navigate", "eval", "snapshot", "a2ui_push", "a2ui_reset"],
"type": "string"
},
"delayMs": {
"type": "number"
},
"gatewayToken": {
"type": "string"
},
"gatewayUrl": {
"type": "string"
},
"height": {
"type": "number"
},
"javaScript": {
"type": "string"
},
"jsonl": {
"type": "string"
},
"jsonlPath": {
"type": "string"
},
"maxWidth": {
"type": "number"
},
"node": {
"type": "string"
},
"outputFormat": {
"enum": ["png", "jpg", "jpeg"],
"type": "string"
},
"quality": {
"type": "number"
},
"target": {
"type": "string"
},
"timeoutMs": {
"type": "number"
},
"url": {
"type": "string"
},
"width": {
"type": "number"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"required": ["action"],
"type": "object"
},
"name": "canvas"
}
]

View File

@@ -1447,5 +1447,71 @@
"type": "object"
},
"name": "web_fetch"
},
{
"description": "Control node canvases (present/hide/navigate/eval/snapshot/A2UI). Use snapshot to capture the rendered UI.",
"inputSchema": {
"properties": {
"action": {
"enum": ["present", "hide", "navigate", "eval", "snapshot", "a2ui_push", "a2ui_reset"],
"type": "string"
},
"delayMs": {
"type": "number"
},
"gatewayToken": {
"type": "string"
},
"gatewayUrl": {
"type": "string"
},
"height": {
"type": "number"
},
"javaScript": {
"type": "string"
},
"jsonl": {
"type": "string"
},
"jsonlPath": {
"type": "string"
},
"maxWidth": {
"type": "number"
},
"node": {
"type": "string"
},
"outputFormat": {
"enum": ["png", "jpg", "jpeg"],
"type": "string"
},
"quality": {
"type": "number"
},
"target": {
"type": "string"
},
"timeoutMs": {
"type": "number"
},
"url": {
"type": "string"
},
"width": {
"type": "number"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"required": ["action"],
"type": "object"
},
"name": "canvas"
}
]

View File

@@ -1413,5 +1413,71 @@
"type": "object"
},
"name": "web_fetch"
},
{
"description": "Control node canvases (present/hide/navigate/eval/snapshot/A2UI). Use snapshot to capture the rendered UI.",
"inputSchema": {
"properties": {
"action": {
"enum": ["present", "hide", "navigate", "eval", "snapshot", "a2ui_push", "a2ui_reset"],
"type": "string"
},
"delayMs": {
"type": "number"
},
"gatewayToken": {
"type": "string"
},
"gatewayUrl": {
"type": "string"
},
"height": {
"type": "number"
},
"javaScript": {
"type": "string"
},
"jsonl": {
"type": "string"
},
"jsonlPath": {
"type": "string"
},
"maxWidth": {
"type": "number"
},
"node": {
"type": "string"
},
"outputFormat": {
"enum": ["png", "jpg", "jpeg"],
"type": "string"
},
"quality": {
"type": "number"
},
"target": {
"type": "string"
},
"timeoutMs": {
"type": "number"
},
"url": {
"type": "string"
},
"width": {
"type": "number"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"required": ["action"],
"type": "object"
},
"name": "canvas"
}
]

View File

@@ -95,7 +95,8 @@
"subagents",
"session_status",
"web_search",
"web_fetch"
"web_fetch",
"canvas"
],
"experimentalRawEvents": true,
"model": "gpt-5.5",
@@ -213,8 +214,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 158
},
"dynamicToolsJson": {
"chars": 49243,
"roughTokens": 12311
"chars": 50870,
"roughTokens": 12718
},
"openClawDeveloperInstructions": {
"chars": 6023,
@@ -225,8 +226,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 7294
},
"totalWithDynamicToolsJson": {
"chars": 78420,
"roughTokens": 19605
"chars": 80047,
"roughTokens": 20012
},
"userInputText": {
"chars": 870,
@@ -588,7 +589,8 @@ Full JSON: `codex-dynamic-tools.discord-group.json`
"subagents",
"session_status",
"web_search",
"web_fetch"
"web_fetch",
"canvas"
]
```

View File

@@ -95,7 +95,8 @@
"subagents",
"session_status",
"web_search",
"web_fetch"
"web_fetch",
"canvas"
],
"experimentalRawEvents": true,
"model": "gpt-5.5",
@@ -213,8 +214,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 158
},
"dynamicToolsJson": {
"chars": 48934,
"roughTokens": 12234
"chars": 50561,
"roughTokens": 12641
},
"openClawDeveloperInstructions": {
"chars": 4999,
@@ -225,8 +226,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 6913
},
"totalWithDynamicToolsJson": {
"chars": 76587,
"roughTokens": 19147
"chars": 78214,
"roughTokens": 19554
},
"userInputText": {
"chars": 370,
@@ -565,7 +566,8 @@ Full JSON: `codex-dynamic-tools.telegram-direct.json`
"subagents",
"session_status",
"web_search",
"web_fetch"
"web_fetch",
"canvas"
]
```

View File

@@ -96,7 +96,8 @@
"subagents",
"session_status",
"web_search",
"web_fetch"
"web_fetch",
"canvas"
],
"experimentalRawEvents": true,
"model": "gpt-5.5",
@@ -214,8 +215,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 158
},
"dynamicToolsJson": {
"chars": 50057,
"roughTokens": 12515
"chars": 51684,
"roughTokens": 12921
},
"openClawDeveloperInstructions": {
"chars": 4999,
@@ -226,8 +227,8 @@ This is the deterministic model-bound layer stack OpenClaw can snapshot for the
"roughTokens": 7693
},
"totalWithDynamicToolsJson": {
"chars": 80828,
"roughTokens": 20207
"chars": 82455,
"roughTokens": 20614
},
"userInputText": {
"chars": 608,
@@ -588,7 +589,8 @@ Full JSON: `codex-dynamic-tools.heartbeat-turn.json`
"subagents",
"session_status",
"web_search",
"web_fetch"
"web_fetch",
"canvas"
]
```