惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
MongoDB | Blog
MongoDB | Blog
GbyAI
GbyAI
L
LangChain Blog
B
Blog
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
U
Unit 42
Last Week in AI
Last Week in AI
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
小众软件
小众软件
I
InfoQ
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
C
Check Point Blog

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
chore(lint): enable stricter oxlint rules · openclaw/open...
steipete · 2026-06-01 · via Recent Commits to openclaw:main

@@ -2,7 +2,7 @@

22

// Secret scanning alert handler for OpenClaw maintainers.

33

// Usage: node secret-scanning.mjs <command> [options]

445-

import { execFileSync, spawnSync } from "node:child_process";

5+

import { spawnSync } from "node:child_process";

66

import crypto from "node:crypto";

77

import fs from "node:fs";

88

import os from "node:os";

@@ -39,7 +39,9 @@ function gh(args, { json = true, allowFailure = false } = {}) {

3939

stderr: proc.stderr,

4040

};

4141

}

42-

if (!json) return proc.stdout;

42+

if (!json) {

43+

return proc.stdout;

44+

}

4345

try {

4446

return JSON.parse(proc.stdout);

4547

} catch {

@@ -70,7 +72,9 @@ export function loadBodyRedactionResult(locationType, resultFile) {

7072

if (!resultFile) {

7173

fail("Body notifications require a redaction result file from redact-body-if-needed");

7274

}

73-

if (!fs.existsSync(resultFile)) fail(`File not found: ${resultFile}`);

75+

if (!fs.existsSync(resultFile)) {

76+

fail(`File not found: ${resultFile}`);

77+

}

74787579

const result = JSON.parse(fs.readFileSync(resultFile, "utf8"));

7680

if (typeof result.notify_required !== "boolean") {

@@ -182,10 +186,11 @@ function fetchDiscussionComment(discussionNumber, discussionCommentDbId) {

182186

failOnGraphQLFailure(gql, `Failed to fetch discussion #${discussionNumber}`);

183187184188

const discussion = gql?.data?.repository?.discussion;

185-

if (!discussion)

189+

if (!discussion) {

186190

fail(

187191

`Discussion #${discussionNumber} not found — it may have been deleted. The alert cannot be processed via this skill.`,

188192

);

193+

}

189194190195

discussionId = discussion.id;

191196

@@ -205,15 +210,18 @@ function fetchDiscussionComment(discussionNumber, discussionCommentDbId) {

205210

`Failed to fetch replies for discussion comment ${topLevelComment.id}`,

206211

);

207212

const replies = replyPage?.data?.node?.replies;

208-

if (!replies)

213+

if (!replies) {

209214

fail(`Failed to paginate replies for discussion comment ${topLevelComment.id}`);

215+

}

210216211217

reply = findDiscussionCommentNode(replies.nodes, discussionCommentDbId);

212218

hasMoreReplies = replies.pageInfo.hasNextPage;

213219

replyCursor = replies.pageInfo.endCursor;

214220

}

215221216-

if (reply) return { discussionId, comment: reply };

222+

if (reply) {

223+

return { discussionId, comment: reply };

224+

}

217225

}

218226219227

hasNextPage = discussion.comments.pageInfo.hasNextPage;

@@ -241,7 +249,9 @@ function createDiscussionComment(discussionNodeId, body, replyToNodeId) {

241249

* Fetch alert metadata + locations. Never exposes .secret.

242250

*/

243251

function cmdFetchAlert(alertNumber) {

244-

if (!alertNumber) fail("Usage: fetch-alert <number>");

252+

if (!alertNumber) {

253+

fail("Usage: fetch-alert <number>");

254+

}

245255246256

const alert = gh(["api", `repos/${REPO}/secret-scanning/alerts/${alertNumber}?hide_secret=true`]);

247257

@@ -280,28 +290,35 @@ function cmdFetchAlert(alertNumber) {

280290

* Saves full body to a temp file. Prints metadata + file path to stdout.

281291

*/

282292

function cmdFetchContent(locationJson) {

283-

if (!locationJson) fail("Usage: fetch-content '<location-json>'");

293+

if (!locationJson) {

294+

fail("Usage: fetch-content '<location-json>'");

295+

}

284296

const location = JSON.parse(locationJson);

285297

const type = location.type;

286298

const details = location.details;

287299288300

if (type === "discussion_comment") {

289301

const commentUrl = details.discussion_comment_url;

290-

if (!commentUrl) fail("No discussion_comment_url in location details");

302+

if (!commentUrl) {

303+

fail("No discussion_comment_url in location details");

304+

}

291305292306

const urlMatch = commentUrl.match(/discussions\/(\d+)#discussioncomment-(\d+)/);

293-

if (!urlMatch) fail(`Cannot parse discussion comment URL: ${commentUrl}`);

307+

if (!urlMatch) {

308+

fail(`Cannot parse discussion comment URL: ${commentUrl}`);

309+

}

294310

const discussionNumber = urlMatch[1];

295311

const discussionCommentDbId = urlMatch[2];

296312297313

const { discussionId, comment } = fetchDiscussionComment(

298314

discussionNumber,

299315

discussionCommentDbId,

300316

);

301-

if (!comment)

317+

if (!comment) {

302318

fail(

303319

`Discussion comment #${discussionCommentDbId} not found in discussion #${discussionNumber}`,

304320

);

321+

}

305322306323

const bodyFile = tmpFile("body.md");

307324

fs.writeFileSync(bodyFile, comment.body || "");

@@ -334,7 +351,9 @@ function cmdFetchContent(locationJson) {

334351

details.issue_comment_url ||

335352

details.pull_request_comment_url ||

336353

details.pull_request_review_comment_url;

337-

if (!commentUrl) fail(`No comment URL in location details`);

354+

if (!commentUrl) {

355+

fail(`No comment URL in location details`);

356+

}

338357339358

const comment = gh(["api", commentUrl]);

340359

const bodyFile = tmpFile("body.md");

@@ -378,7 +397,9 @@ function cmdFetchContent(locationJson) {

378397

);

379398

} else if (type === "issue_body") {

380399

const issueUrl = details.issue_body_url || details.issue_url;

381-

if (!issueUrl) fail("No issue URL in location details");

400+

if (!issueUrl) {

401+

fail("No issue URL in location details");

402+

}

382403383404

const issue = gh(["api", issueUrl]);

384405

const bodyFile = tmpFile("body.md");

@@ -414,7 +435,9 @@ function cmdFetchContent(locationJson) {

414435

);

415436

} else if (type === "pull_request_body") {

416437

const prUrl = details.pull_request_body_url || details.pull_request_url;

417-

if (!prUrl) fail("No PR URL in location details");

438+

if (!prUrl) {

439+

fail("No PR URL in location details");

440+

}

418441419442

const pr = gh(["api", prUrl]);

420443

const bodyFile = tmpFile("body.md");

@@ -490,7 +513,9 @@ function cmdRedactBody(kind, number, bodyFile) {

490513

if (!kind || !number || !bodyFile) {

491514

fail("Usage: redact-body <issue|pr> <number> <redacted-body-file>");

492515

}

493-

if (!fs.existsSync(bodyFile)) fail(`File not found: ${bodyFile}`);

516+

if (!fs.existsSync(bodyFile)) {

517+

fail(`File not found: ${bodyFile}`);

518+

}

494519495520

const endpoint =

496521

kind === "pr" ? `repos/${REPO}/pulls/${number}` : `repos/${REPO}/issues/${number}`;

@@ -509,8 +534,12 @@ function cmdRedactBodyIfNeeded(kind, number, currentBodyFile, redactedBodyFile,

509534

"Usage: redact-body-if-needed <issue|pr> <number> <current-body-file> <redacted-body-file> <result-file>",

510535

);

511536

}

512-

if (!fs.existsSync(currentBodyFile)) fail(`File not found: ${currentBodyFile}`);

513-

if (!fs.existsSync(redactedBodyFile)) fail(`File not found: ${redactedBodyFile}`);

537+

if (!fs.existsSync(currentBodyFile)) {

538+

fail(`File not found: ${currentBodyFile}`);

539+

}

540+

if (!fs.existsSync(redactedBodyFile)) {

541+

fail(`File not found: ${redactedBodyFile}`);

542+

}

514543515544

const currentBody = fs.readFileSync(currentBodyFile, "utf8");

516545

const redactedBody = fs.readFileSync(redactedBodyFile, "utf8");

@@ -541,7 +570,9 @@ function cmdRedactBodyIfNeeded(kind, number, currentBodyFile, redactedBodyFile,

541570

* Delete a comment (and all its edit history).

542571

*/

543572

function cmdDeleteComment(commentId) {

544-

if (!commentId) fail("Usage: delete-comment <comment-id>");

573+

if (!commentId) {

574+

fail("Usage: delete-comment <comment-id>");

575+

}

545576

gh(["api", `repos/${REPO}/issues/comments/${commentId}`, "-X", "DELETE"], { json: false });

546577

console.log(JSON.stringify({ ok: true, deleted_comment_id: Number(commentId) }));

547578

}

@@ -551,7 +582,9 @@ function cmdDeleteComment(commentId) {

551582

* Delete a discussion comment via GraphQL (and all its edit history).

552583

*/

553584

function cmdDeleteDiscussionComment(nodeId) {

554-

if (!nodeId) fail("Usage: delete-discussion-comment <node-id>");

585+

if (!nodeId) {

586+

fail("Usage: delete-discussion-comment <node-id>");

587+

}

555588

const result = ghGraphQL(

556589

`mutation { deleteDiscussionComment(input: { id: "${nodeId}" }) { comment { id } } }`,

557590

);

@@ -566,9 +599,12 @@ function cmdDeleteDiscussionComment(nodeId) {

566599

* Create a new discussion comment via GraphQL.

567600

*/

568601

function cmdRecreateDiscussionComment(discussionNodeId, bodyFile, replyToNodeId) {

569-

if (!discussionNodeId || !bodyFile)

602+

if (!discussionNodeId || !bodyFile) {

570603

fail("Usage: recreate-discussion-comment <discussion-node-id> <body-file> [reply-to-node-id]");

571-

if (!fs.existsSync(bodyFile)) fail(`File not found: ${bodyFile}`);

604+

}

605+

if (!fs.existsSync(bodyFile)) {

606+

fail(`File not found: ${bodyFile}`);

607+

}

572608573609

const body = fs.readFileSync(bodyFile, "utf8");

574610

const newComment = createDiscussionComment(discussionNodeId, body, replyToNodeId);

@@ -586,8 +622,12 @@ function cmdRecreateDiscussionComment(discussionNodeId, bodyFile, replyToNodeId)

586622

* Create a new comment from a file.

587623

*/

588624

function cmdRecreateComment(issueNumber, bodyFile) {

589-

if (!issueNumber || !bodyFile) fail("Usage: recreate-comment <issue-number> <body-file>");

590-

if (!fs.existsSync(bodyFile)) fail(`File not found: ${bodyFile}`);

625+

if (!issueNumber || !bodyFile) {

626+

fail("Usage: recreate-comment <issue-number> <body-file>");

627+

}

628+

if (!fs.existsSync(bodyFile)) {

629+

fail(`File not found: ${bodyFile}`);

630+

}

591631592632

const result = gh([

593633

"api",

@@ -715,7 +755,9 @@ function cmdNotify(target, author, locationType, secretTypes, replyToNodeId) {

715755

* Close a secret scanning alert.

716756

*/

717757

function cmdResolve(alertNumber, resolution, comment) {

718-

if (!alertNumber) fail("Usage: resolve <alert-number> [resolution] [comment]");

758+

if (!alertNumber) {

759+

fail("Usage: resolve <alert-number> [resolution] [comment]");

760+

}

719761720762

const res = resolution || "revoked";

721763

const resComment = comment || "Content redacted and author notified to rotate credentials.";

@@ -773,8 +815,12 @@ function cmdListOpen() {

773815

* Print a formatted summary table from a JSON results file.

774816

*/

775817

function cmdSummary(jsonFile) {

776-

if (!jsonFile) fail("Usage: summary <json-file>");

777-

if (!fs.existsSync(jsonFile)) fail(`File not found: ${jsonFile}`);

818+

if (!jsonFile) {

819+

fail("Usage: summary <json-file>");

820+

}

821+

if (!fs.existsSync(jsonFile)) {

822+

fail(`File not found: ${jsonFile}`);

823+

}

778824779825

const results = JSON.parse(fs.readFileSync(jsonFile, "utf8"));

780826

const lines = [];