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

推荐订阅源

H
Help Net Security
T
ThreatConnect
SecWiki News
SecWiki News
F
Future of Privacy Forum
AWS News Blog
AWS News Blog
C
Cisco Blogs
A
Arctic Wolf
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Scott Helme
Scott Helme
V
V2EX
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News | PayPal Newsroom
Schneier on Security
Schneier on Security
NISL@THU
NISL@THU
Microsoft Azure Blog
Microsoft Azure Blog
量子位
The Hacker News
The Hacker News
Stack Overflow Blog
Stack Overflow Blog
Security Latest
Security Latest
M
Microsoft Research Blog - Microsoft Research
Google Online Security Blog
Google Online Security Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
InfoQ
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Martin Fowler
Martin Fowler
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Troy Hunt's Blog
F
Fox-IT International blog
S
Security @ Cisco Blogs
博客园 - 司徒正美
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Comments on: Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LINUX DO - 最新话题
GbyAI
GbyAI
Project Zero
Project Zero
腾讯CDC
T
Tailwind CSS Blog

Recent Commits to openclaw:main

refactor: reuse realtime output activity in google meet (#86665) fix: prefer source public artifacts in source checkouts · openclaw/openclaw@c87957d test: type child process spawn mock · openclaw/openclaw@65a2105 test(installer): cover rocky cli installs · openclaw/openclaw@fe33747 docs: update changelog for landed fixes fix: dampen repeated device-required probes fix(ui): keep local file markdown links inert fix(update): avoid duplicate plugin smoke failures fix(gateway): cap retained compaction checkpoint bytes fix: stabilize tests and reduce plugin memory churn perf: reduce runtime metadata hotpath churn · openclaw/openclaw@1d21224 refactor: share realtime output activity tracking (#86661) fix(memory-wiki): bound compile page reads (#86660) · openclaw/openclaw@acbdb8c test(qa-matrix): use larger media coverage jpeg fix(cli): reject unknown command help roots (#81083) (thanks @YB0y) · openclaw/openclaw@bec7d56 test: improve test profiling helpers · openclaw/openclaw@68ab48b perf: reduce fuzzy matching allocations · openclaw/openclaw@ec7ad3b perf: reduce runtime cache churn · openclaw/openclaw@1531fe2 refactor: reuse forced consult coordinator in discord voice (#86656) · openclaw/openclaw@0164fd5 fix(scripts): drain codex-cli metadata stdout (#84239) (thanks @Iftek… fix(test): avoid discord voice tts activation tax · openclaw/openclaw@75ac0b5 fix(codex): disable native thread personality (#85891) (thanks @lastg… · openclaw/openclaw@0f35ec2 Refactor realtime voice turn context tracking (#86650) fix(discord): surface silent reply-delivery skips and remove runtime.… · openclaw/openclaw@3a48366 test(discord): cover deliver-lambda abort-skip path via processDiscor… · openclaw/openclaw@48adcb1 docs: update changelog for landed bug fixes · openclaw/openclaw@75c6cf2 test(qa-matrix): use valid media coverage jpeg · openclaw/openclaw@0f54221 fix(gmail-watcher): strip listeners from old process after settleProc… · openclaw/openclaw@0a38932 fix(gmail-watcher): prevent TDZ in settleProcess and guard exit handl… · openclaw/openclaw@94968c8 fix(hooks): stop existing Gmail watcher before re-entry to prevent leaks fix(codex): honor yolo app-server approval policy · openclaw/openclaw@7b30291 fix(usage-cost): invalidate durable cache on missing-cost semantics c… · openclaw/openclaw@9c79a0f fix(usage-cost): preserve transport-recorded positive cost for unpric… · openclaw/openclaw@6e85869 fix(usage-cost): only flag catalog-default zeros, preserve operator-c… · openclaw/openclaw@1670249 fix: treat zero-rate usage cost as unknown · openclaw/openclaw@116c600 fix(usage-cost): surface unpriced-model spend as missingCostEntries i… · openclaw/openclaw@1cc0a96 fix(irc): normalize channel route ids · openclaw/openclaw@9cb1e47 test(irc): cover transient channel join · openclaw/openclaw@c4c80ce fix(irc): store inbound channel routes as channel:#name and join befo… · openclaw/openclaw@63dee51 fix(test): harden macos onboarding e2e · openclaw/openclaw@cd96542 fix(agents): strip markdown code spans from IDENTITY.md values and la… · openclaw/openclaw@55c9a6b perf: reduce runtime cache churn · openclaw/openclaw@5b6d03e fix(pi-runner): flush blocks after compaction retry (#85288) (thanks … · openclaw/openclaw@0d4575a fix(gateway): abort stale agent runs on restart · openclaw/openclaw@a122d80 fix(ui): harden control e2e browser setup · openclaw/openclaw@4424daf fix(telegram): keep overlapping DM replies deliverable (#85361) (than… · openclaw/openclaw@0f67dfd fix(openai): route compaction through Codex auth provider (#86408) · openclaw/openclaw@f4cfa01 refactor: share realtime forced consult coordination · openclaw/openclaw@5dccba7 test(qa-lab): add runtime confidence reports build: refresh dependency pins (#86628) · openclaw/openclaw@cda7c30 test: port release validation stabilizers · openclaw/openclaw@9f7485e fix(cron): stop forcing message tool for delivery · openclaw/openclaw@c51fa0d fix(google): omit request config with cached content test: stabilize release validation test harnesses fix(test): bound kitchen sink command output · openclaw/openclaw@f1197ed fix(discord): stabilize realtime wake-name feedback test(config): guard legacy agentRuntime regression perf: precompute audio resample kernels fix(codex): allow env api-key app-server bootstrap · openclaw/openclaw@009b18c refactor: reuse shared coercion helpers (#86419) · openclaw/openclaw@77d9ac3 fix(cron): preserve runtime snapshot for isolated delivery · openclaw/openclaw@a98660e fix(test): model active assistant failover attempts · openclaw/openclaw@c55bee5 docs: update changelog for bug sweep landings test: fix mock signatures for tsgo · openclaw/openclaw@aa05c5c docs: document fail-closed behavior for rejected modelPatterns · openclaw/openclaw@36f269d fix(security): guard plugin modelPatterns with compileSafeRegex · openclaw/openclaw@117e082 docs(manifest): note safe-regex validation for modelPatterns · openclaw/openclaw@e7c7ee4 style: use bracket notation for __openclaw to satisfy no-underscore-d… · openclaw/openclaw@9a6c161 fix(security): escape field names in transcript regex extraction · openclaw/openclaw@fe8d99d test: tighten oversized metadata assertion to check exact id in __ope… · openclaw/openclaw@aff8e64 fix(logging): exit on stdout/stderr EPIPE instead of spinning · openclaw/openclaw@2aa5f17 fix(logging): preserve failure exit on EPIPE · openclaw/openclaw@623a60a fix(logging): keep string failure codes on EPIPE · openclaw/openclaw@78a1e7d fix(scripts): docs-spellcheck.sh fails on bash 3.2 with set -u · openclaw/openclaw@fef57f9 fix(docs): keep spellcheck bash 3.2-compatible · openclaw/openclaw@778fa87 fix(test): assert e2e agent reply payloads · openclaw/openclaw@74f3a1e test(gateway): pin live gateway models to pi runtime · openclaw/openclaw@c88f660 perf: speed up local TUI startup · openclaw/openclaw@a0023fb refactor: share realtime voice activation helpers (#86615) · openclaw/openclaw@d0ab0d9 fix(feishu): render native presentation buttons (#86588) · openclaw/openclaw@170e0aa fix(test): narrow plugin gauntlet prebuild · openclaw/openclaw@423f7d2 fix: route Discord gateway metadata through proxy (#86601) · openclaw/openclaw@5b6d409 fix: tighten Discord voice wake matching (#86595) · openclaw/openclaw@f00a912 refactor(logging): share diagnostic message lifecycle · openclaw/openclaw@baab4cf fix(cron): restore suspended lanes to default concurrency · openclaw/openclaw@e844d1d fix(auth): emit one-shot doctor-pointer warning for Keychain-only leg… · openclaw/openclaw@a61d530 fix(codex): recover stale preflight bindings (#86602) · openclaw/openclaw@9b9d897 fix(cron): preserve unsupported payload rows on writes · openclaw/openclaw@c916906 fix(cron): canonicalize preserved row ids · openclaw/openclaw@985bc93 test(cron): pin sequential duration regression · openclaw/openclaw@8351556 docs: update changelog for cron preservation (#86415) · openclaw/openclaw@bdc6b32 build: bump qs to patched release · openclaw/openclaw@9330b76 fix(status): prefer active OAuth for runtime aliases chore(acpx): bump bundled acpx to 0.10.0 · openclaw/openclaw@407cf8e docs: make changelog release-owned · openclaw/openclaw@c0f2d89 fix(google): stop appending preview to flash lite · openclaw/openclaw@915c820 docs: update changelog for bug sweep landings · openclaw/openclaw@cd7994f fix(crabbox): detect timed macos js commands · openclaw/openclaw@44bb0be fix(mantis): release telegram user leases on startup failure · openclaw/openclaw@cf27567 fix(agents): deliver stale cron media completions · openclaw/openclaw@f01b2a8
fix(test): harden bundled plugin install sweep · openclaw/openclaw@84929e4
vincentkoc · 2026-05-26 · via Recent Commits to openclaw:main

@@ -4,8 +4,13 @@ import os from "node:os";

44

import path from "node:path";

55

import process from "node:process";

66

import { setTimeout as delay } from "node:timers/promises";

7+

import { fileURLToPath } from "node:url";

7889

const TOKEN = "bundled-plugin-runtime-smoke-token";

10+

const OUTPUT_CAPTURE_CHARS = readPositiveInt(

11+

process.env.OPENCLAW_BUNDLED_PLUGIN_RUNTIME_OUTPUT_CHARS,

12+

1024 * 1024,

13+

);

914

const WATCHDOG_MS = readPositiveInt(process.env.OPENCLAW_BUNDLED_PLUGIN_RUNTIME_WATCHDOG_MS, 1000);

1015

const READY_TIMEOUT_MS = readPositiveInt(

1116

process.env.OPENCLAW_BUNDLED_PLUGIN_RUNTIME_READY_MS,

@@ -136,27 +141,58 @@ function isNonEmptyString(value) {

136141

return typeof value === "string" && value.trim().length > 0;

137142

}

138143144+

export function appendBoundedOutput(buffer, chunk, maxChars = OUTPUT_CAPTURE_CHARS) {

145+

const nextText = buffer.text + String(chunk);

146+

if (nextText.length <= maxChars) {

147+

return { text: nextText, truncatedChars: buffer.truncatedChars };

148+

}

149+

const truncatedChars = buffer.truncatedChars + nextText.length - maxChars;

150+

return { text: nextText.slice(-maxChars), truncatedChars };

151+

}

152+153+

function formatCapturedOutput(label, buffer) {

154+

if (!buffer.text) {

155+

return "";

156+

}

157+

const prefix =

158+

buffer.truncatedChars > 0

159+

? `[${label} truncated ${buffer.truncatedChars} chars; showing tail]\n`

160+

: "";

161+

return `${prefix}${buffer.text}`;

162+

}

163+139164

function runCommand(command, args, options = {}) {

140165

return new Promise((resolve, reject) => {

141166

const child = childProcess.spawn(command, args, {

142167

stdio: ["ignore", "pipe", "pipe"],

143168

...options,

144169

});

145-

let stdout = "";

146-

let stderr = "";

170+

let stdout = { text: "", truncatedChars: 0 };

171+

let stderr = { text: "", truncatedChars: 0 };

147172

child.stdout?.on("data", (chunk) => {

148-

stdout += String(chunk);

173+

stdout = appendBoundedOutput(stdout, chunk);

149174

});

150175

child.stderr?.on("data", (chunk) => {

151-

stderr += String(chunk);

176+

stderr = appendBoundedOutput(stderr, chunk);

152177

});

153178

child.on("error", reject);

154179

child.on("close", (status, signal) => {

155180

if (status === 0) {

156-

resolve({ stdout, stderr });

181+

resolve({

182+

stdout: stdout.text,

183+

stderr: stderr.text,

184+

stdoutTruncatedChars: stdout.truncatedChars,

185+

stderrTruncatedChars: stderr.truncatedChars,

186+

});

157187

return;

158188

}

159-

const detail = [stdout, stderr].filter(Boolean).join("\n").trim();

189+

const detail = [

190+

formatCapturedOutput("stdout", stdout),

191+

formatCapturedOutput("stderr", stderr),

192+

]

193+

.filter(Boolean)

194+

.join("\n")

195+

.trim();

160196

reject(

161197

new Error(

162198

`${command} ${args.join(" ")} failed with ${signal || status}${detail ? `\n${detail}` : ""}`,

@@ -726,7 +762,7 @@ async function smokeOpenAiTts(pluginIndex) {

726762

}

727763

}

728764729-

function createIsolatedStateEnv(label) {

765+

export function createIsolatedStateEnv(label) {

730766

const root = fs.mkdtempSync(path.join(os.tmpdir(), `openclaw-${label}-`));

731767

const home = path.join(root, "home");

732768

const stateDir = path.join(home, ".openclaw");

@@ -735,7 +771,8 @@ function createIsolatedStateEnv(label) {

735771

return {

736772

...process.env,

737773

HOME: home,

738-

OPENCLAW_HOME: stateDir,

774+

USERPROFILE: home,

775+

OPENCLAW_HOME: home,

739776

OPENCLAW_STATE_DIR: stateDir,

740777

OPENCLAW_CONFIG_PATH: configPath,

741778

};

@@ -752,16 +789,22 @@ function tailText(text) {

752789

return text.split(/\r?\n/u).slice(-120).join("\n");

753790

}

754791755-

const [command, pluginId, pluginDir, requiresConfigRaw, pluginIndexRaw, pluginRoot, provider] =

756-

process.argv.slice(2);

757-

const pluginIndex = Number.parseInt(pluginIndexRaw || "0", 10);

792+

export async function main(argv = process.argv.slice(2)) {

793+

const [command, pluginId, pluginDir, requiresConfigRaw, pluginIndexRaw, pluginRoot, provider] =

794+

argv;

795+

const pluginIndex = Number.parseInt(pluginIndexRaw || "0", 10);

796+797+

if (command === "plugin") {

798+

await smokePlugin(pluginId, pluginDir, requiresConfigRaw === "1", pluginIndex, pluginRoot);

799+

} else if (command === "tts-global-disable") {

800+

await smokeTtsGlobalDisable(pluginId, pluginDir, provider, pluginIndex, pluginRoot);

801+

} else if (command === "tts-openai-live") {

802+

await smokeOpenAiTts(pluginIndex);

803+

} else {

804+

throw new Error(`Unknown runtime smoke command: ${command || "(missing)"}`);

805+

}

806+

}

758807759-

if (command === "plugin") {

760-

await smokePlugin(pluginId, pluginDir, requiresConfigRaw === "1", pluginIndex, pluginRoot);

761-

} else if (command === "tts-global-disable") {

762-

await smokeTtsGlobalDisable(pluginId, pluginDir, provider, pluginIndex, pluginRoot);

763-

} else if (command === "tts-openai-live") {

764-

await smokeOpenAiTts(pluginIndex);

765-

} else {

766-

throw new Error(`Unknown runtime smoke command: ${command || "(missing)"}`);

808+

if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {

809+

await main();

767810

}