Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
156 lines
4.8 KiB
TypeScript
156 lines
4.8 KiB
TypeScript
// Package script tests validate root package script invariants.
|
|
import fs from "node:fs";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
type RootPackageJson = {
|
|
scripts: Record<string, string>;
|
|
};
|
|
|
|
const ENV_ASSIGNMENT_RE = /^[A-Za-z_][A-Za-z0-9_]*=/u;
|
|
const NODE_OPTIONS_WITH_VALUE = new Set([
|
|
"--conditions",
|
|
"--env-file",
|
|
"--env-file-if-exists",
|
|
"--import",
|
|
"--loader",
|
|
"--max-old-space-size",
|
|
"--require",
|
|
"--test-name-pattern",
|
|
"--test-reporter",
|
|
"-C",
|
|
"-r",
|
|
]);
|
|
|
|
function readPackageJson(): RootPackageJson {
|
|
return JSON.parse(fs.readFileSync("package.json", "utf8")) as RootPackageJson;
|
|
}
|
|
|
|
function tokenizeCommand(command: string): string[] {
|
|
return (
|
|
command
|
|
.match(/"[^"]*"|'[^']*'|[^\s]+/gu)
|
|
?.map((token) => token.replace(/^(['"])(.*)\1$/u, "$2")) ?? []
|
|
);
|
|
}
|
|
|
|
function extractNodeScriptTargets(script: string): string[] {
|
|
return script.split(/\s*(?:&&|\|\||;)\s*/u).flatMap((command) => {
|
|
const tokens = tokenizeCommand(command);
|
|
let index = tokens[0] === "env" ? 1 : 0;
|
|
|
|
while (ENV_ASSIGNMENT_RE.test(tokens[index] ?? "")) {
|
|
index += 1;
|
|
}
|
|
|
|
if (tokens[index] !== "node") {
|
|
return [];
|
|
}
|
|
|
|
for (let tokenIndex = index + 1; tokenIndex < tokens.length; tokenIndex += 1) {
|
|
const token = tokens[tokenIndex];
|
|
if (!token) {
|
|
continue;
|
|
}
|
|
if (token.startsWith("scripts/")) {
|
|
return [token];
|
|
}
|
|
if (token === "--") {
|
|
continue;
|
|
}
|
|
if (token.startsWith("--") && token.includes("=")) {
|
|
continue;
|
|
}
|
|
if (NODE_OPTIONS_WITH_VALUE.has(token)) {
|
|
tokenIndex += 1;
|
|
continue;
|
|
}
|
|
if (token.startsWith("-")) {
|
|
continue;
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
return [];
|
|
});
|
|
}
|
|
|
|
describe("package scripts", () => {
|
|
it("finds node script targets after env assignments and valued node options", () => {
|
|
expect(
|
|
extractNodeScriptTargets(
|
|
"FOO=1 node --import tsx scripts/release-check.ts && node --max-old-space-size=8192 scripts/plugin-sdk-surface-report.mjs && env BAR=1 node -r tsx scripts/check.ts",
|
|
),
|
|
).toEqual([
|
|
"scripts/release-check.ts",
|
|
"scripts/plugin-sdk-surface-report.mjs",
|
|
"scripts/check.ts",
|
|
]);
|
|
});
|
|
|
|
it("keeps direct node script targets present in the source checkout", () => {
|
|
const packageJson = readPackageJson();
|
|
const missingTargets = Object.entries(packageJson.scripts).flatMap(([name, script]) =>
|
|
extractNodeScriptTargets(script)
|
|
.filter((target) => !fs.existsSync(target))
|
|
.map((target) => `${name}: ${target}`),
|
|
);
|
|
|
|
expect(missingTargets).toEqual([]);
|
|
});
|
|
|
|
it("keeps direct Node package scripts off POSIX-only env assignment prefixes", () => {
|
|
const packageJson = readPackageJson();
|
|
const directNodeEnvScripts = Object.entries(packageJson.scripts).flatMap(([name, script]) =>
|
|
script
|
|
.split(/\s*(?:&&|\|\||;)\s*/u)
|
|
.filter((command) => {
|
|
const tokens = tokenizeCommand(command);
|
|
let index = tokens[0] === "env" ? 1 : 0;
|
|
const hasEnvPrefix = ENV_ASSIGNMENT_RE.test(tokens[index] ?? "");
|
|
while (ENV_ASSIGNMENT_RE.test(tokens[index] ?? "")) {
|
|
index += 1;
|
|
}
|
|
return hasEnvPrefix && tokens[index] === "node";
|
|
})
|
|
.map((command) => `${name}: ${command}`),
|
|
);
|
|
|
|
expect(directNodeEnvScripts).toEqual([]);
|
|
});
|
|
|
|
it("enables live cache validation in the package script", () => {
|
|
expect(readPackageJson().scripts["test:live:cache"]).toBe(
|
|
"node scripts/run-with-env.mjs OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 -- node --import tsx scripts/check-live-cache.ts",
|
|
);
|
|
});
|
|
|
|
it("gives the plugin SDK usage scan enough heap for repository-wide analysis", () => {
|
|
expect(readPackageJson().scripts["plugin-sdk:usage"]).toBe(
|
|
"node --max-old-space-size=8192 --import tsx scripts/analyze-plugin-sdk-usage.ts",
|
|
);
|
|
});
|
|
|
|
it("runs runtime postbuild before plugin SDK strict export checks", () => {
|
|
expect(readPackageJson().scripts["build:plugin-sdk:strict-smoke"]).toBe(
|
|
"node scripts/tsdown-build.mjs && node scripts/runtime-postbuild.mjs && node scripts/run-with-env.mjs OPENCLAW_PLUGIN_SDK_CANONICAL_DTS=1 -- node --experimental-strip-types scripts/write-plugin-sdk-entry-dts.ts && node scripts/check-plugin-sdk-exports.mjs",
|
|
);
|
|
});
|
|
|
|
it("uses the shipped package launcher for npm start", () => {
|
|
expect(readPackageJson().scripts.start).toBe("node openclaw.mjs");
|
|
});
|
|
|
|
it("runs generated module formatting coverage in Windows CI", () => {
|
|
expect(readPackageJson().scripts["test:windows:ci"]).toContain(
|
|
"test/scripts/format-generated-module.test.ts",
|
|
);
|
|
});
|
|
|
|
it("runs env launcher coverage in Windows CI", () => {
|
|
expect(readPackageJson().scripts["test:windows:ci"]).toContain(
|
|
"test/scripts/run-with-env.test.ts",
|
|
);
|
|
});
|
|
});
|