chore: Enable linting in `scripts`.

main
cpojer 2026-01-31 21:29:14 +09:00
parent 0ffc251704
commit 1838ab019b
No known key found for this signature in database
GPG Key ID: C29F94A3201118AF
21 changed files with 314 additions and 124 deletions

View File

@ -32,7 +32,6 @@
"Swabble/",
"vendor/",
"extensions/",
"scripts/",
"ui/"
]
}

View File

@ -18,20 +18,28 @@ const DEFAULT_RUNS = 10;
function parseArg(flag: string): string | undefined {
const idx = process.argv.indexOf(flag);
if (idx === -1) return undefined;
if (idx === -1) {
return undefined;
}
return process.argv[idx + 1];
}
function parseRuns(raw: string | undefined): number {
if (!raw) return DEFAULT_RUNS;
if (!raw) {
return DEFAULT_RUNS;
}
const parsed = Number(raw);
if (!Number.isFinite(parsed) || parsed <= 0) return DEFAULT_RUNS;
if (!Number.isFinite(parsed) || parsed <= 0) {
return DEFAULT_RUNS;
}
return Math.floor(parsed);
}
function median(values: number[]): number {
if (values.length === 0) return 0;
const sorted = [...values].sort((a, b) => a - b);
if (values.length === 0) {
return 0;
}
const sorted = [...values].toSorted((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
if (sorted.length % 2 === 0) {
return Math.round((sorted[mid - 1] + sorted[mid]) / 2);

View File

@ -5,7 +5,6 @@ import { fileURLToPath } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const binDir = path.join(root, "bin");
const scriptPath = path.join(root, "scripts", "docs-list.js");
const binPath = path.join(binDir, "docs-list");
fs.mkdirSync(binDir, { recursive: true });

View File

@ -13,7 +13,9 @@ function parseArgs(argv: string[]): ParsedArgs {
const arg = argv[index];
if (arg === "--max") {
const next = argv[index + 1];
if (!next || Number.isNaN(Number(next))) throw new Error("Missing/invalid --max value");
if (!next || Number.isNaN(Number(next))) {
throw new Error("Missing/invalid --max value");
}
maxLines = Number(next);
index++;
continue;
@ -43,7 +45,9 @@ async function countLines(filePath: string): Promise<number> {
async function main() {
// Makes `... | head` safe.
process.stdout.on("error", (error: NodeJS.ErrnoException) => {
if (error.code === "EPIPE") process.exit(0);
if (error.code === "EPIPE") {
process.exit(0);
}
throw error;
});
@ -58,9 +62,11 @@ async function main() {
const offenders = results
.filter((result) => result.lines > maxLines)
.sort((a, b) => b.lines - a.lines);
.toSorted((a, b) => b.lines - a.lines);
if (!offenders.length) return;
if (!offenders.length) {
return;
}
// Minimal, grep-friendly output.
for (const offender of offenders) {

View File

@ -26,7 +26,9 @@ function copyHookMetadata() {
const entries = fs.readdirSync(srcBundled, { withFileTypes: true });
for (const entry of entries) {
if (!entry.isDirectory()) continue;
if (!entry.isDirectory()) {
continue;
}
const hookName = entry.name;
const srcHookDir = path.join(srcBundled, hookName);

View File

@ -12,7 +12,9 @@ type Args = {
const mask = (value: string) => {
const compact = value.trim();
if (!compact) return "missing";
if (!compact) {
return "missing";
}
const edge = compact.length >= 12 ? 6 : 4;
return `${compact.slice(0, edge)}${compact.slice(-edge)}`;
};
@ -48,7 +50,9 @@ const loadAuthProfiles = (agentId: string) => {
process.env.CLAWDBOT_STATE_DIR?.trim() ||
path.join(os.homedir(), ".openclaw");
const authPath = path.join(stateRoot, "agents", agentId, "agent", "auth-profiles.json");
if (!fs.existsSync(authPath)) throw new Error(`Missing: ${authPath}`);
if (!fs.existsSync(authPath)) {
throw new Error(`Missing: ${authPath}`);
}
const store = JSON.parse(fs.readFileSync(authPath, "utf8")) as {
profiles?: Record<string, { provider?: string; type?: string; token?: string; key?: string }>;
};
@ -61,9 +65,13 @@ const pickAnthropicTokens = (store: {
const profiles = store.profiles ?? {};
const found: Array<{ profileId: string; token: string }> = [];
for (const [id, cred] of Object.entries(profiles)) {
if (cred?.provider !== "anthropic") continue;
if (cred?.provider !== "anthropic") {
continue;
}
const token = cred.type === "token" ? cred.token?.trim() : undefined;
if (token) found.push({ profileId: id, token });
if (token) {
found.push({ profileId: id, token });
}
}
return found;
};
@ -87,7 +95,9 @@ const readClaudeCliKeychain = (): {
expiresAt?: number;
scopes?: string[];
} | null => {
if (process.platform !== "darwin") return null;
if (process.platform !== "darwin") {
return null;
}
try {
const raw = execFileSync(
"security",
@ -96,9 +106,13 @@ const readClaudeCliKeychain = (): {
);
const parsed = JSON.parse(raw.trim()) as Record<string, unknown>;
const oauth = parsed?.claudeAiOauth as Record<string, unknown> | undefined;
if (!oauth || typeof oauth !== "object") return null;
if (!oauth || typeof oauth !== "object") {
return null;
}
const accessToken = oauth.accessToken;
if (typeof accessToken !== "string" || !accessToken.trim()) return null;
if (typeof accessToken !== "string" || !accessToken.trim()) {
return null;
}
const expiresAt = typeof oauth.expiresAt === "number" ? oauth.expiresAt : undefined;
const scopes = Array.isArray(oauth.scopes)
? oauth.scopes.filter((v): v is string => typeof v === "string")
@ -110,10 +124,18 @@ const readClaudeCliKeychain = (): {
};
const chromeServiceNameForPath = (cookiePath: string): string => {
if (cookiePath.includes("/Arc/")) return "Arc Safe Storage";
if (cookiePath.includes("/BraveSoftware/")) return "Brave Safe Storage";
if (cookiePath.includes("/Microsoft Edge/")) return "Microsoft Edge Safe Storage";
if (cookiePath.includes("/Chromium/")) return "Chromium Safe Storage";
if (cookiePath.includes("/Arc/")) {
return "Arc Safe Storage";
}
if (cookiePath.includes("/BraveSoftware/")) {
return "Brave Safe Storage";
}
if (cookiePath.includes("/Microsoft Edge/")) {
return "Microsoft Edge Safe Storage";
}
if (cookiePath.includes("/Chromium/")) {
return "Chromium Safe Storage";
}
return "Chrome Safe Storage";
};
@ -132,12 +154,18 @@ const readKeychainPassword = (service: string): string | null => {
};
const decryptChromeCookieValue = (encrypted: Buffer, service: string): string | null => {
if (encrypted.length < 4) return null;
if (encrypted.length < 4) {
return null;
}
const prefix = encrypted.subarray(0, 3).toString("utf8");
if (prefix !== "v10" && prefix !== "v11") return null;
if (prefix !== "v10" && prefix !== "v11") {
return null;
}
const password = readKeychainPassword(service);
if (!password) return null;
if (!password) {
return null;
}
const key = crypto.pbkdf2Sync(password, "saltysalt", 1003, 16, "sha1");
const iv = Buffer.alloc(16, 0x20);
@ -172,10 +200,16 @@ const queryChromeCookieDb = (cookieDb: string): string | null => {
],
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 5000 },
).trim();
if (!out) return null;
if (out.startsWith("sk-ant-")) return out;
if (!out) {
return null;
}
if (out.startsWith("sk-ant-")) {
return out;
}
const hex = out.replace(/[^0-9A-Fa-f]/g, "");
if (!hex) return null;
if (!hex) {
return null;
}
const buf = Buffer.from(hex, "hex");
const service = chromeServiceNameForPath(cookieDb);
const decrypted = decryptChromeCookieValue(buf, service);
@ -209,7 +243,9 @@ const queryFirefoxCookieDb = (cookieDb: string): string | null => {
};
const findClaudeSessionKey = (): { sessionKey: string; source: string } | null => {
if (process.platform !== "darwin") return null;
if (process.platform !== "darwin") {
return null;
}
const firefoxRoot = path.join(
os.homedir(),
@ -221,9 +257,13 @@ const findClaudeSessionKey = (): { sessionKey: string; source: string } | null =
if (fs.existsSync(firefoxRoot)) {
for (const entry of fs.readdirSync(firefoxRoot)) {
const db = path.join(firefoxRoot, entry, "cookies.sqlite");
if (!fs.existsSync(db)) continue;
if (!fs.existsSync(db)) {
continue;
}
const value = queryFirefoxCookieDb(db);
if (value) return { sessionKey: value, source: `firefox:${db}` };
if (value) {
return { sessionKey: value, source: `firefox:${db}` };
}
}
}
@ -236,15 +276,21 @@ const findClaudeSessionKey = (): { sessionKey: string; source: string } | null =
];
for (const root of chromeCandidates) {
if (!fs.existsSync(root)) continue;
if (!fs.existsSync(root)) {
continue;
}
const profiles = fs
.readdirSync(root)
.filter((name) => name === "Default" || name.startsWith("Profile "));
for (const profile of profiles) {
const db = path.join(root, profile, "Cookies");
if (!fs.existsSync(db)) continue;
if (!fs.existsSync(db)) {
continue;
}
const value = queryChromeCookieDb(db);
if (value) return { sessionKey: value, source: `chromium:${db}` };
if (value) {
return { sessionKey: value, source: `chromium:${db}` };
}
}
}

View File

@ -32,8 +32,14 @@ function compactStrings(values) {
if (value === null || value === undefined) {
continue;
}
const normalized = String(value).trim();
if (normalized.length > 0) {
const normalized =
typeof value === "string"
? value.trim()
: typeof value === "number" || typeof value === "boolean"
? String(value).trim()
: null;
if (normalized?.length > 0) {
result.push(normalized);
}
}
@ -62,7 +68,7 @@ function walkMarkdownFiles(dir, base = dir) {
files.push(relative(base, fullPath));
}
}
return files.sort((a, b) => a.localeCompare(b));
return files.toSorted((a, b) => a.localeCompare(b));
}
/**

View File

@ -18,7 +18,9 @@ const userAgent =
const timeoutMs = 30_000;
function truncate(value: string, max = 180): string {
if (!value) return "";
if (!value) {
return "";
}
return value.length > max ? `${value.slice(0, max)}` : value;
}
@ -89,8 +91,12 @@ async function run() {
}
console.log(`local: ${localStatus} len=${localText.length} title=${truncate(localTitle, 80)}`);
if (localError) console.log(`local error: ${localError}`);
if (localText) console.log(`local sample: ${truncate(localText)}`);
if (localError) {
console.log(`local error: ${localError}`);
}
if (localText) {
console.log(`local sample: ${truncate(localText)}`);
}
if (apiKey) {
try {
@ -111,8 +117,12 @@ async function run() {
80,
)} status=${firecrawl.status ?? "n/a"}`,
);
if (firecrawl.warning) console.log(`firecrawl warning: ${firecrawl.warning}`);
if (firecrawl.text) console.log(`firecrawl sample: ${truncate(firecrawl.text)}`);
if (firecrawl.warning) {
console.log(`firecrawl warning: ${firecrawl.warning}`);
}
if (firecrawl.text) {
console.log(`firecrawl sample: ${truncate(firecrawl.text)}`);
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.log(`firecrawl: error ${message}`);

View File

@ -19,7 +19,9 @@ function runGitCommand(args, options = {}) {
}
function splitNullDelimited(value) {
if (!value) return [];
if (!value) {
return [];
}
const text = String(value);
return text.split("\0").filter(Boolean);
}
@ -44,7 +46,9 @@ function findPartiallyStagedFiles(stagedFiles, unstagedFiles) {
}
function filterOutPartialTargets(targets, partialTargets) {
if (partialTargets.length === 0) return targets;
if (partialTargets.length === 0) {
return targets;
}
const partial = new Set(partialTargets.map(normalizeGitPath));
return targets.filter((filePath) => !partial.has(normalizeGitPath(filePath)));
}
@ -66,7 +70,9 @@ function resolveOxfmtCommand(repoRoot) {
function getGitPaths(args, repoRoot) {
const result = runGitCommand(args, { cwd: repoRoot });
if (result.status !== 0) return [];
if (result.status !== 0) {
return [];
}
return splitNullDelimited(result.stdout ?? "");
}
@ -79,7 +85,9 @@ function formatFiles(repoRoot, oxfmt, files) {
}
function stageFiles(repoRoot, files) {
if (files.length === 0) return true;
if (files.length === 0) {
return true;
}
const result = runGitCommand(["add", "--", ...files], { cwd: repoRoot, stdio: "inherit" });
return result.status === 0;
}
@ -91,7 +99,9 @@ function main() {
repoRoot,
);
const targets = filterOxfmtTargets(staged);
if (targets.length === 0) return;
if (targets.length === 0) {
return;
}
const unstaged = getGitPaths(["diff", "--name-only", "-z"], repoRoot);
const partial = findPartiallyStagedFiles(targets, unstaged);
@ -104,7 +114,9 @@ function main() {
}
const filteredTargets = filterOutPartialTargets(targets, partial);
if (filteredTargets.length === 0) return;
if (filteredTargets.length === 0) {
return;
}
const oxfmt = resolveOxfmtCommand(repoRoot);
if (!oxfmt) {

View File

@ -10,10 +10,18 @@ function detectPackageManager(ua = process.env.npm_config_user_agent ?? "") {
// - "npm/10.9.4 node/v22.12.0 linux x64"
// - "bun/1.2.2"
const normalized = String(ua).trim();
if (normalized.startsWith("pnpm/")) return "pnpm";
if (normalized.startsWith("bun/")) return "bun";
if (normalized.startsWith("npm/")) return "npm";
if (normalized.startsWith("yarn/")) return "yarn";
if (normalized.startsWith("pnpm/")) {
return "pnpm";
}
if (normalized.startsWith("bun/")) {
return "bun";
}
if (normalized.startsWith("npm/")) {
return "npm";
}
if (normalized.startsWith("yarn/")) {
return "yarn";
}
return "unknown";
}
@ -28,38 +36,42 @@ function getRepoRoot() {
}
function ensureExecutable(targetPath) {
if (process.platform === "win32") return;
if (!fs.existsSync(targetPath)) return;
if (process.platform === "win32") {
return;
}
if (!fs.existsSync(targetPath)) {
return;
}
try {
const mode = fs.statSync(targetPath).mode & 0o777;
if (mode & 0o100) return;
if (mode & 0o100) {
return;
}
fs.chmodSync(targetPath, 0o755);
} catch (err) {
console.warn(`[postinstall] chmod failed: ${err}`);
}
}
function hasGit(repoRoot) {
const result = spawnSync("git", ["--version"], {
cwd: repoRoot,
stdio: "ignore",
});
return result.status === 0;
}
function extractPackageName(key) {
if (key.startsWith("@")) {
const idx = key.indexOf("@", 1);
if (idx === -1) return key;
if (idx === -1) {
return key;
}
return key.slice(0, idx);
}
const idx = key.lastIndexOf("@");
if (idx <= 0) return key;
if (idx <= 0) {
return key;
}
return key.slice(0, idx);
}
function stripPrefix(p) {
if (p.startsWith("a/") || p.startsWith("b/")) return p.slice(2);
if (p.startsWith("a/") || p.startsWith("b/")) {
return p.slice(2);
}
return p;
}
@ -89,7 +101,9 @@ function parsePatch(patchText) {
i += 1;
// Skip index line(s)
while (i < lines.length && lines[i].startsWith("index ")) i += 1;
while (i < lines.length && lines[i].startsWith("index ")) {
i += 1;
}
if (i < lines.length && lines[i].startsWith("--- ")) {
file.oldPath = stripPrefix(lines[i].slice(4).trim());
@ -103,7 +117,9 @@ function parsePatch(patchText) {
while (i < lines.length && lines[i].startsWith("@@")) {
const header = lines[i];
const match = /^@@\s+(-\d+(?:,\d+)?)\s+(\+\d+(?:,\d+)?)\s+@@/.exec(header);
if (!match) throw new Error(`invalid hunk header: ${header}`);
if (!match) {
throw new Error(`invalid hunk header: ${header}`);
}
const oldRange = parseRange(match[1]);
const newRange = parseRange(match[2]);
i += 1;
@ -111,7 +127,9 @@ function parsePatch(patchText) {
const hunkLines = [];
while (i < lines.length) {
const line = lines[i];
if (line.startsWith("@@") || line.startsWith("diff --git ")) break;
if (line.startsWith("@@") || line.startsWith("diff --git ")) {
break;
}
if (line === "") {
i += 1;
continue;
@ -148,7 +166,9 @@ function readFileLines(targetPath) {
const raw = fs.readFileSync(targetPath, "utf-8");
const hasTrailingNewline = raw.endsWith("\n");
const parts = raw.split("\n");
if (hasTrailingNewline) parts.pop();
if (hasTrailingNewline) {
parts.pop();
}
return { lines: parts, hasTrailingNewline };
}
@ -235,7 +255,9 @@ function applyPatchSet({ patchText, targetDir }) {
resolvedTarget = fs.realpathSync(resolvedTarget);
const files = parsePatch(patchText);
if (files.length === 0) return;
if (files.length === 0) {
return;
}
for (const filePatch of files) {
applyPatchToFile(resolvedTarget, filePatch);
@ -253,14 +275,20 @@ function applyPatchFile({ patchPath, targetDir }) {
function trySetupCompletion(repoRoot) {
// Skip in CI or if explicitly disabled
if (process.env.CI || process.env.OPENCLAW_SKIP_COMPLETION_SETUP) return;
if (process.env.CI || process.env.OPENCLAW_SKIP_COMPLETION_SETUP) {
return;
}
const binPath = path.join(repoRoot, "openclaw.mjs");
if (!fs.existsSync(binPath)) return;
if (!fs.existsSync(binPath)) {
return;
}
// In development, dist might not exist yet during postinstall
const distEntry = path.join(repoRoot, "dist", "index.js");
if (!fs.existsSync(distEntry)) return;
if (!fs.existsSync(distEntry)) {
return;
}
try {
// Run with OPENCLAW_SKIP_POSTINSTALL to avoid any weird recursion,
@ -270,7 +298,7 @@ function trySetupCompletion(repoRoot) {
stdio: "inherit",
env: { ...process.env, OPENCLAW_SKIP_POSTINSTALL: "1" },
});
} catch (err) {
} catch {
// Ignore errors to not break install
}
}
@ -294,9 +322,13 @@ function main() {
// Bun does not support pnpm.patchedDependencies. Apply these patch files to
// node_modules packages as a best-effort compatibility layer.
for (const [key, relPatchPath] of Object.entries(patched)) {
if (typeof relPatchPath !== "string" || !relPatchPath.trim()) continue;
if (typeof relPatchPath !== "string" || !relPatchPath.trim()) {
continue;
}
const pkgName = extractPackageName(String(key));
if (!pkgName) continue;
if (!pkgName) {
continue;
}
applyPatchFile({
targetDir: path.join("node_modules", ...pkgName.split("/")),
patchPath: relPatchPath,

View File

@ -72,7 +72,9 @@ function camelCase(input: string) {
function safeName(name: string) {
const cc = camelCase(name.replace(/-/g, "_"));
if (reserved.has(cc)) return `_${cc}`;
if (reserved.has(cc)) {
return `_${cc}`;
}
return cc;
}
@ -86,11 +88,15 @@ function swiftType(schema: JsonSchema, required: boolean): string {
const named = schemaNameByObject.get(schema as object);
if (named) {
base = named;
} else if (t === "string") base = "String";
else if (t === "integer") base = "Int";
else if (t === "number") base = "Double";
else if (t === "boolean") base = "Bool";
else if (t === "array") {
} else if (t === "string") {
base = "String";
} else if (t === "integer") {
base = "Int";
} else if (t === "number") {
base = "Double";
} else if (t === "boolean") {
base = "Bool";
} else if (t === "array") {
base = `[${swiftType(schema.items ?? { type: "Any" }, true)}]`;
} else if (schema.enum) {
base = "String";
@ -213,7 +219,9 @@ async function generate() {
// Value structs
for (const [name, schema] of definitions) {
if (name === "GatewayFrame") continue;
if (name === "GatewayFrame") {
continue;
}
if (schema.type === "object") {
parts.push(emitStruct(name, schema));
}

View File

@ -23,7 +23,9 @@ async function runFetch(url: string, readability: boolean) {
},
sandboxed: false,
});
if (!tool) throw new Error("web_fetch tool is disabled");
if (!tool) {
throw new Error("web_fetch tool is disabled");
}
const result = await tool.execute("test", { url, extractMode: "markdown" });
return result.details as {
text?: string;
@ -35,7 +37,9 @@ async function runFetch(url: string, readability: boolean) {
}
function truncate(value: string, max = 160): string {
if (!value) return "";
if (!value) {
return "";
}
return value.length > max ? `${value.slice(0, max)}` : value;
}
@ -50,7 +54,9 @@ async function run() {
80,
)}`,
);
if (readable.text) console.log(`readability sample: ${truncate(readable.text)}`);
if (readable.text) {
console.log(`readability sample: ${truncate(readable.text)}`);
}
}
}

View File

@ -27,7 +27,9 @@ const statMtime = (filePath) => {
const isExcludedSource = (filePath) => {
const relativePath = path.relative(srcRoot, filePath);
if (relativePath.startsWith("..")) return false;
if (relativePath.startsWith("..")) {
return false;
}
return (
relativePath.endsWith(".test.ts") ||
relativePath.endsWith(".test.tsx") ||
@ -40,7 +42,9 @@ const findLatestMtime = (dirPath, shouldSkip) => {
const queue = [dirPath];
while (queue.length > 0) {
const current = queue.pop();
if (!current) continue;
if (!current) {
continue;
}
let entries = [];
try {
entries = fs.readdirSync(current, { withFileTypes: true });
@ -53,10 +57,16 @@ const findLatestMtime = (dirPath, shouldSkip) => {
queue.push(fullPath);
continue;
}
if (!entry.isFile()) continue;
if (shouldSkip?.(fullPath)) continue;
if (!entry.isFile()) {
continue;
}
if (shouldSkip?.(fullPath)) {
continue;
}
const mtime = statMtime(fullPath);
if (mtime == null) continue;
if (mtime == null) {
continue;
}
if (latest == null || mtime > latest) {
latest = mtime;
}
@ -66,23 +76,35 @@ const findLatestMtime = (dirPath, shouldSkip) => {
};
const shouldBuild = () => {
if (env.OPENCLAW_FORCE_BUILD === "1") return true;
if (env.OPENCLAW_FORCE_BUILD === "1") {
return true;
}
const stampMtime = statMtime(buildStampPath);
if (stampMtime == null) return true;
if (statMtime(distEntry) == null) return true;
if (stampMtime == null) {
return true;
}
if (statMtime(distEntry) == null) {
return true;
}
for (const filePath of configFiles) {
const mtime = statMtime(filePath);
if (mtime != null && mtime > stampMtime) return true;
if (mtime != null && mtime > stampMtime) {
return true;
}
}
const srcMtime = findLatestMtime(srcRoot, isExcludedSource);
if (srcMtime != null && srcMtime > stampMtime) return true;
if (srcMtime != null && srcMtime > stampMtime) {
return true;
}
return false;
};
const logRunner = (message) => {
if (env.OPENCLAW_RUNNER_LOG === "0") return;
if (env.OPENCLAW_RUNNER_LOG === "0") {
return;
}
process.stderr.write(`[openclaw] ${message}\n`);
};

View File

@ -20,11 +20,17 @@ function runGitCommand(args, options = {}) {
}
function ensureExecutable(targetPath) {
if (process.platform === "win32") return;
if (!fs.existsSync(targetPath)) return;
if (process.platform === "win32") {
return;
}
if (!fs.existsSync(targetPath)) {
return;
}
try {
const mode = fs.statSync(targetPath).mode & 0o777;
if (mode & 0o100) return;
if (mode & 0o100) {
return;
}
fs.chmodSync(targetPath, 0o755);
} catch (err) {
console.warn(`[setup-git-hooks] chmod failed: ${err}`);
@ -41,7 +47,9 @@ function isGitRepo({ repoRoot = getRepoRoot(), runGit = runGitCommand } = {}) {
cwd: repoRoot,
stdio: "pipe",
});
if (result.status !== 0) return false;
if (result.status !== 0) {
return false;
}
return String(result.stdout ?? "").trim() === "true";
}

View File

@ -44,7 +44,9 @@ function replaceBlockLines(
];
const replacement = replacementLines.join("\n");
if (!after) return `${before}${replacement}`;
if (!after) {
return `${before}${replacement}`;
}
return `${before}${replacement}\n${after}`;
}

View File

@ -6,7 +6,6 @@ type PackageJson = {
version?: string;
};
const root = resolve(".");
const rootPackagePath = resolve("package.json");
const rootPackage = JSON.parse(readFileSync(rootPackagePath, "utf8")) as PackageJson;
const targetVersion = rootPackage.version;
@ -25,9 +24,13 @@ const changelogged: string[] = [];
const skipped: string[] = [];
function ensureChangelogEntry(changelogPath: string, version: string): boolean {
if (!existsSync(changelogPath)) return false;
if (!existsSync(changelogPath)) {
return false;
}
const content = readFileSync(changelogPath, "utf8");
if (content.includes(`## ${version}`)) return false;
if (content.includes(`## ${version}`)) {
return false;
}
const entry = `## ${version}\n\n### Changes\n- Version alignment with core OpenClaw release numbers.\n\n`;
if (content.startsWith("# Changelog\n\n")) {
const next = content.replace("# Changelog\n\n", `# Changelog\n\n${entry}`);

View File

@ -74,11 +74,15 @@ const runOnce = (entry, extraArgs = []) =>
});
const run = async (entry) => {
if (shardCount <= 1) return runOnce(entry);
if (shardCount <= 1) {
return runOnce(entry);
}
for (let shardIndex = 1; shardIndex <= shardCount; shardIndex += 1) {
// eslint-disable-next-line no-await-in-loop
const code = await runOnce(entry, ["--shard", `${shardIndex}/${shardCount}`]);
if (code !== 0) return code;
if (code !== 0) {
return code;
}
}
return 0;
};

View File

@ -28,7 +28,9 @@ function which(cmd) {
for (const ext of extensions) {
const candidate = path.join(entry, process.platform === "win32" ? `${cmd}${ext}` : cmd);
try {
if (fs.existsSync(candidate)) return candidate;
if (fs.existsSync(candidate)) {
return candidate;
}
} catch {
// ignore
}
@ -42,7 +44,9 @@ function which(cmd) {
function resolveRunner() {
const pnpm = which("pnpm");
if (pnpm) return { cmd: pnpm, kind: "pnpm" };
if (pnpm) {
return { cmd: pnpm, kind: "pnpm" };
}
return null;
}
@ -54,7 +58,9 @@ function run(cmd, args) {
shell: process.platform === "win32",
});
child.on("exit", (code, signal) => {
if (signal) process.exit(1);
if (signal) {
process.exit(1);
}
process.exit(code ?? 1);
});
}
@ -66,8 +72,12 @@ function runSync(cmd, args, envOverride) {
env: envOverride ?? process.env,
shell: process.platform === "win32",
});
if (result.signal) process.exit(1);
if ((result.status ?? 1) !== 0) process.exit(result.status ?? 1);
if (result.signal) {
process.exit(1);
}
if ((result.status ?? 1) !== 0) {
process.exit(result.status ?? 1);
}
}
function depsInstalled(kind) {
@ -114,8 +124,9 @@ if (action !== "install" && !script) {
process.exit(2);
}
if (action === "install") run(runner.cmd, ["install", ...rest]);
else {
if (action === "install") {
run(runner.cmd, ["install", ...rest]);
} else {
if (!depsInstalled(action === "test" ? "test" : "build")) {
const installEnv =
action === "build" ? { ...process.env, NODE_ENV: "production" } : process.env;

View File

@ -229,7 +229,7 @@ const lines: string[] = [];
for (let i = 0; i < entries.length; i += PER_LINE) {
const chunk = entries.slice(i, i + PER_LINE);
const parts = chunk.map((entry) => {
return `<a href=\"${entry.html_url}\"><img src=\"${entry.avatar_url}\" width=\"48\" height=\"48\" alt=\"${entry.display}\" title=\"${entry.display}\"/></a>`;
return `<a href="${entry.html_url}"><img src="${entry.avatar_url}" width="48" height="48" alt="${entry.display}" title="${entry.display}"/></a>`;
});
lines.push(` ${parts.join(" ")}`);
}
@ -243,7 +243,7 @@ if (start === -1 || end === -1) {
throw new Error("README.md missing clawtributors block");
}
const next = `${readme.slice(0, start)}<p align=\"left\">\n${block}${readme.slice(end)}`;
const next = `${readme.slice(0, start)}<p align="left">\n${block}${readme.slice(end)}`;
writeFileSync(readmePath, next);
console.log(`Updated README clawtributors: ${entries.length} entries`);
@ -419,7 +419,7 @@ function parseReadmeEntries(
}
const block = content.slice(start, end);
const entries: Array<{ display: string; html_url: string; avatar_url: string }> = [];
const linked = /<a href=\"([^\"]+)\"><img src=\"([^\"]+)\"[^>]*alt=\"([^\"]+)\"[^>]*>/g;
const linked = /<a href="([^"]+)"><img src="([^"]+)"[^>]*alt="([^"]+)"[^>]*>/g;
for (const match of block.matchAll(linked)) {
const [, href, src, alt] = match;
if (!href || !src || !alt) {
@ -427,7 +427,7 @@ function parseReadmeEntries(
}
entries.push({ html_url: href, avatar_url: src, display: alt });
}
const standalone = /<img src=\"([^\"]+)\"[^>]*alt=\"([^\"]+)\"[^>]*>/g;
const standalone = /<img src="([^"]+)"[^>]*alt="([^"]+)"[^>]*>/g;
for (const match of block.matchAll(standalone)) {
const [, src, alt] = match;
if (!src || !alt) {
@ -442,7 +442,7 @@ function parseReadmeEntries(
}
function loginFromUrl(url: string): string | null {
const match = /^https?:\/\/github\.com\/([^\/?#]+)/i.exec(url);
const match = /^https?:\/\/github\.com\/([^/?#]+)/i.exec(url);
if (!match) {
return null;
}

View File

@ -19,7 +19,9 @@ const readPackageVersion = () => {
const resolveCommit = () => {
const envCommit = process.env.GIT_COMMIT?.trim() || process.env.GIT_SHA?.trim();
if (envCommit) return envCommit;
if (envCommit) {
return envCommit;
}
try {
return execSync("git rev-parse HEAD", {
cwd: rootDir,

View File

@ -13,9 +13,13 @@ type RunResult = {
function pickAnthropicEnv(): { type: "oauth" | "api"; value: string } | null {
const oauth = process.env.ANTHROPIC_OAUTH_TOKEN?.trim();
if (oauth) return { type: "oauth", value: oauth };
if (oauth) {
return { type: "oauth", value: oauth };
}
const api = process.env.ANTHROPIC_API_KEY?.trim();
if (api) return { type: "api", value: api };
if (api) {
return { type: "api", value: api };
}
return null;
}