Vendor OpenClaw source as Adolf fork baseline
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
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
This commit is contained in:
386
scripts/check-docs-mdx.mjs
Normal file
386
scripts/check-docs-mdx.mjs
Normal file
@@ -0,0 +1,386 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Validates docs MDX files for syntax and repository-specific conventions.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { compile } from "@mdx-js/mdx";
|
||||
import {
|
||||
checkMintlifyAccordionIndentation,
|
||||
MINTLIFY_ACCORDION_INDENT_MESSAGE,
|
||||
} from "./lib/mintlify-accordion.mjs";
|
||||
|
||||
const MINTLIFY_LANGUAGE_CODES = new Set([
|
||||
"en",
|
||||
"cn",
|
||||
"zh",
|
||||
"zh-Hans",
|
||||
"zh-Hant",
|
||||
"es",
|
||||
"fr",
|
||||
"fr-CA",
|
||||
"fr-ca",
|
||||
"ja",
|
||||
"jp",
|
||||
"ja-jp",
|
||||
"pt",
|
||||
"pt-BR",
|
||||
"de",
|
||||
"ko",
|
||||
"it",
|
||||
"ru",
|
||||
"ro",
|
||||
"cs",
|
||||
"id",
|
||||
"ar",
|
||||
"tr",
|
||||
"hi",
|
||||
"sv",
|
||||
"no",
|
||||
"lv",
|
||||
"nl",
|
||||
"uk",
|
||||
"vi",
|
||||
"pl",
|
||||
"uz",
|
||||
"he",
|
||||
"ca",
|
||||
"fi",
|
||||
"hu",
|
||||
]);
|
||||
|
||||
const POISON_TEXT_PATTERNS = [
|
||||
{
|
||||
pattern: /\banalysis\s+to=functions\./iu,
|
||||
message: "Leaked tool-call channel marker.",
|
||||
},
|
||||
{
|
||||
pattern: /\b(?:commentary|final)\s+to=functions\./iu,
|
||||
message: "Leaked tool-call channel marker.",
|
||||
},
|
||||
{
|
||||
pattern: /\bfunctions\.(?:read|write|exec|search|run)\b/iu,
|
||||
message: "Leaked internal tool name.",
|
||||
},
|
||||
{
|
||||
pattern: /\b[A-Za-z_\u3400-\u9fff][\w\u3400-\u9fff-]*_input=\{/u,
|
||||
message: "Leaked tool-call input payload.",
|
||||
},
|
||||
{
|
||||
pattern: /<\/?openclaw_docs_i18n_input>/iu,
|
||||
message: "Leaked docs i18n prompt wrapper.",
|
||||
},
|
||||
{
|
||||
pattern: /\/home\/runner\/work\//u,
|
||||
message: "Leaked GitHub Actions workspace path.",
|
||||
},
|
||||
{
|
||||
pattern: /彩神马争霸/u,
|
||||
message: "Known spam/gambling text from a poisoned translation.",
|
||||
},
|
||||
];
|
||||
|
||||
function parsePositiveIntegerArg(raw, label) {
|
||||
const text = String(raw ?? "").trim();
|
||||
if (!/^\d+$/u.test(text)) {
|
||||
throw new Error(`${label} must be a positive integer`);
|
||||
}
|
||||
const value = Number(text);
|
||||
if (!Number.isSafeInteger(value) || value < 1) {
|
||||
throw new Error(`${label} must be a positive integer`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function readRequiredValue(argv, index, label) {
|
||||
const value = argv[index + 1];
|
||||
if (!value || value.startsWith("-")) {
|
||||
throw new Error(`${label} requires a value`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses docs MDX check arguments.
|
||||
*/
|
||||
export function parseArgs(argv) {
|
||||
const roots = [];
|
||||
let jsonOut = "";
|
||||
let maxErrors = 50;
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const part = argv[index];
|
||||
if (part === "--json-out") {
|
||||
jsonOut = readRequiredValue(argv, index, "--json-out");
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (part === "--max-errors") {
|
||||
maxErrors = parsePositiveIntegerArg(
|
||||
readRequiredValue(argv, index, "--max-errors"),
|
||||
"--max-errors",
|
||||
);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (part.startsWith("--")) {
|
||||
throw new Error(`unknown arg: ${part}`);
|
||||
}
|
||||
roots.push(part);
|
||||
}
|
||||
|
||||
return {
|
||||
roots: roots.length ? roots : ["docs"],
|
||||
jsonOut,
|
||||
maxErrors,
|
||||
};
|
||||
}
|
||||
|
||||
function walkMarkdownFiles(entryPath, out = []) {
|
||||
const stat = fs.statSync(entryPath);
|
||||
if (stat.isFile()) {
|
||||
if (/\.mdx?$/i.test(entryPath)) {
|
||||
out.push(path.resolve(entryPath));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
for (const entry of fs.readdirSync(entryPath, { withFileTypes: true })) {
|
||||
if (entry.name === "node_modules" || entry.name === ".git") {
|
||||
continue;
|
||||
}
|
||||
walkMarkdownFiles(path.join(entryPath, entry.name), out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function stripFrontmatter(raw) {
|
||||
if (!raw.startsWith("---\n") && !raw.startsWith("---\r\n")) {
|
||||
return raw;
|
||||
}
|
||||
|
||||
const lines = raw.split(/\r?\n/u);
|
||||
for (let index = 1; index < lines.length; index += 1) {
|
||||
if (lines[index] === "---" || lines[index] === "...") {
|
||||
return lines.slice(index + 1).join("\n");
|
||||
}
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
|
||||
function formatMdxError(filePath, error) {
|
||||
const place = error?.place ?? error?.position;
|
||||
const start = place?.start ?? place;
|
||||
const line = typeof start?.line === "number" ? start.line : undefined;
|
||||
const column = typeof start?.column === "number" ? start.column : undefined;
|
||||
return {
|
||||
type: "mdx",
|
||||
file: filePath,
|
||||
line,
|
||||
column,
|
||||
message: String(error?.reason ?? error?.message ?? error).split("\n")[0],
|
||||
};
|
||||
}
|
||||
|
||||
function checkMintlifyMdxStructure(filePath, raw) {
|
||||
return checkMintlifyAccordionIndentation(stripFrontmatter(raw)).map((error) => ({
|
||||
type: "mintlify-mdx",
|
||||
file: filePath,
|
||||
line: error.line,
|
||||
column: error.column,
|
||||
message: MINTLIFY_ACCORDION_INDENT_MESSAGE,
|
||||
}));
|
||||
}
|
||||
|
||||
function lineColumnForIndex(raw, offset) {
|
||||
const prefix = raw.slice(0, offset);
|
||||
const lines = prefix.split(/\r?\n/u);
|
||||
return {
|
||||
line: lines.length,
|
||||
column: lines.at(-1).length + 1,
|
||||
};
|
||||
}
|
||||
|
||||
function checkPoisonText(filePath, raw) {
|
||||
const errors = [];
|
||||
for (const { pattern, message } of POISON_TEXT_PATTERNS) {
|
||||
const match = pattern.exec(raw);
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
const location = lineColumnForIndex(raw, match.index);
|
||||
errors.push({
|
||||
type: "poison-text",
|
||||
file: filePath,
|
||||
line: location.line,
|
||||
column: location.column,
|
||||
message,
|
||||
});
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
async function checkMdxFile(filePath) {
|
||||
const raw = fs.readFileSync(filePath, "utf8");
|
||||
const poisonErrors = checkPoisonText(filePath, raw);
|
||||
if (poisonErrors.length > 0) {
|
||||
return poisonErrors;
|
||||
}
|
||||
const structureErrors = checkMintlifyMdxStructure(filePath, raw);
|
||||
if (structureErrors.length > 0) {
|
||||
return structureErrors;
|
||||
}
|
||||
const value = stripFrontmatter(raw);
|
||||
await compile(
|
||||
{ path: filePath, value },
|
||||
{
|
||||
development: false,
|
||||
jsx: false,
|
||||
},
|
||||
);
|
||||
return [];
|
||||
}
|
||||
|
||||
function findDocsJsonPaths(roots) {
|
||||
const paths = new Set();
|
||||
for (const root of roots) {
|
||||
const absolute = path.resolve(root);
|
||||
if (!fs.existsSync(absolute)) {
|
||||
continue;
|
||||
}
|
||||
const stat = fs.statSync(absolute);
|
||||
if (stat.isFile() && path.basename(absolute) === "docs.json") {
|
||||
paths.add(absolute);
|
||||
continue;
|
||||
}
|
||||
if (stat.isDirectory()) {
|
||||
const docsJsonPath = path.join(absolute, "docs.json");
|
||||
if (fs.existsSync(docsJsonPath)) {
|
||||
paths.add(docsJsonPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [...paths];
|
||||
}
|
||||
|
||||
function collectNavigationLanguages(value, out = []) {
|
||||
if (Array.isArray(value)) {
|
||||
for (const item of value) {
|
||||
collectNavigationLanguages(item, out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
if (!value || typeof value !== "object") {
|
||||
return out;
|
||||
}
|
||||
if (typeof value.language === "string") {
|
||||
out.push(value.language);
|
||||
}
|
||||
for (const child of Object.values(value)) {
|
||||
if (child && typeof child === "object") {
|
||||
collectNavigationLanguages(child, out);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function checkDocsJson(filePath) {
|
||||
const errors = [];
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
||||
} catch (error) {
|
||||
return [
|
||||
{
|
||||
type: "docs-json",
|
||||
file: filePath,
|
||||
message: `Invalid JSON: ${String(error?.message ?? error)}`,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const languages = collectNavigationLanguages(data?.navigation);
|
||||
for (const language of languages) {
|
||||
if (!MINTLIFY_LANGUAGE_CODES.has(language)) {
|
||||
errors.push({
|
||||
type: "docs-json",
|
||||
file: filePath,
|
||||
message: `Unsupported Mintlify navigation language: ${language}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
function relativize(root, filePath) {
|
||||
const relative = path.relative(root, filePath);
|
||||
return relative && !relative.startsWith("..") ? relative : filePath;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const startedAt = Date.now();
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const cwd = process.cwd();
|
||||
const roots = args.roots.map((root) => path.resolve(root));
|
||||
const files = [
|
||||
...new Set(
|
||||
roots.flatMap((root) => {
|
||||
if (!fs.existsSync(root)) {
|
||||
throw new Error(`path does not exist: ${root}`);
|
||||
}
|
||||
return walkMarkdownFiles(root);
|
||||
}),
|
||||
),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
|
||||
const errors = [];
|
||||
for (const docsJsonPath of findDocsJsonPaths(args.roots)) {
|
||||
errors.push(...checkDocsJson(docsJsonPath));
|
||||
}
|
||||
|
||||
for (const file of files) {
|
||||
try {
|
||||
errors.push(...(await checkMdxFile(file)));
|
||||
} catch (error) {
|
||||
errors.push(formatMdxError(file, error));
|
||||
if (errors.length >= args.maxErrors) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const report = {
|
||||
files: files.length,
|
||||
errors: errors.map((error) => Object.assign({}, error, { file: relativize(cwd, error.file) })),
|
||||
ms: Date.now() - startedAt,
|
||||
};
|
||||
|
||||
if (args.jsonOut) {
|
||||
fs.mkdirSync(path.dirname(path.resolve(args.jsonOut)), { recursive: true });
|
||||
fs.writeFileSync(args.jsonOut, `${JSON.stringify(report, null, 2)}\n`);
|
||||
}
|
||||
|
||||
if (report.errors.length === 0) {
|
||||
console.log(`Docs MDX check passed (${report.files} files, ${report.ms}ms).`);
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(`Docs MDX check failed (${report.errors.length} error(s), ${report.files} files).`);
|
||||
for (const error of report.errors) {
|
||||
const location =
|
||||
error.line && error.column ? `${error.file}:${error.line}:${error.column}` : error.file;
|
||||
console.error(`- ${location}: ${error.message}`);
|
||||
}
|
||||
process.exitCode = 1;
|
||||
}
|
||||
|
||||
const isMain = process.argv[1] ? fileURLToPath(import.meta.url) === process.argv[1] : false;
|
||||
|
||||
if (isMain) {
|
||||
main().catch(
|
||||
/** @param {unknown} error */ (error) => {
|
||||
console.error(error?.stack ?? error);
|
||||
process.exit(1);
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user