diff --git a/extensions/discord/src/voice/realtime.ts b/extensions/discord/src/voice/realtime.ts index b19d73b067c8..010a2cd51efd 100644 --- a/extensions/discord/src/voice/realtime.ts +++ b/extensions/discord/src/voice/realtime.ts @@ -1,5 +1,5 @@ // Discord plugin module implements realtime behavior. -import { PassThrough } from "node:stream"; +import { PassThrough, pipeline } from "node:stream"; import type { DiscordAccountConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { asDateTimestampMs, @@ -814,7 +814,15 @@ export class DiscordRealtimeVoiceSession implements VoiceRealtimeSession { this.resetOutputStream("opus-encode-error"); }); opusStream.once("close", () => this.handleOutputStreamClosed(stream, "stream-close")); - stream.pipe(opusStream); + pipeline(stream, opusStream, (err) => { + if (!err) { + return; + } + logger.warn( + `discord voice: realtime output pipeline failed guild=${this.params.entry.guildId} channel=${this.params.entry.channelId}: ${formatErrorMessage(err)}`, + ); + this.resetOutputStream("output-pipeline-error"); + }); if (this.outputPacedBuffer.length > 0) { stream.write(this.outputPacedBuffer); this.outputPacedBuffer = Buffer.alloc(0); diff --git a/extensions/tlon/src/urbit/story.ts b/extensions/tlon/src/urbit/story.ts index f61cfde00fba..8ed53a9c4026 100644 --- a/extensions/tlon/src/urbit/story.ts +++ b/extensions/tlon/src/urbit/story.ts @@ -129,7 +129,7 @@ function parseInlineMarkdown(text: string): StoryInline[] { // Plain text: consume until next special character or URL start // Exclude : and / to allow URL detection to work (stops before https://) - const plainMatch = remaining.match(/^[^*_`~[#~\n:/]+/); + const plainMatch = remaining.match(/^[^*_`~[#\n:/]+/); if (plainMatch) { result.push(plainMatch[0]); remaining = remaining.slice(plainMatch[0].length); diff --git a/extensions/workboard/src/store.ts b/extensions/workboard/src/store.ts index e4c035653fef..f4f58b1ee18b 100644 --- a/extensions/workboard/src/store.ts +++ b/extensions/workboard/src/store.ts @@ -434,6 +434,21 @@ function normalizeNotificationSubscription( throw new Error("notification subscription needs cardId, sessionKey, runId, or target."); } const eventKinds = normalizeNotificationKinds(input.eventKinds); + const preservedFields: Partial = {}; + if (fallback) { + if (fallback.lastEventAt) { + preservedFields.lastEventAt = fallback.lastEventAt; + } + if (fallback.lastEventId) { + preservedFields.lastEventId = fallback.lastEventId; + } + if (fallback.lastEventSequence) { + preservedFields.lastEventSequence = fallback.lastEventSequence; + } + if (fallback.deliveredEventIds?.length) { + preservedFields.deliveredEventIds = fallback.deliveredEventIds; + } + } return { id: fallback?.id ?? randomUUID(), boardId, @@ -442,12 +457,7 @@ function normalizeNotificationSubscription( ...(runId ? { runId } : {}), ...(target ? { target } : {}), ...(eventKinds ? { eventKinds } : {}), - ...(fallback?.lastEventAt ? { lastEventAt: fallback.lastEventAt } : {}), - ...(fallback?.lastEventId ? { lastEventId: fallback.lastEventId } : {}), - ...(fallback?.lastEventSequence ? { lastEventSequence: fallback.lastEventSequence } : {}), - ...(fallback?.deliveredEventIds?.length - ? { deliveredEventIds: fallback.deliveredEventIds } - : {}), + ...preservedFields, createdAt: fallback?.createdAt ?? now, updatedAt: now, }; diff --git a/packages/tool-call-repair/src/payload.ts b/packages/tool-call-repair/src/payload.ts index 64528d4c4ffd..183c61103aeb 100644 --- a/packages/tool-call-repair/src/payload.ts +++ b/packages/tool-call-repair/src/payload.ts @@ -291,21 +291,11 @@ function consumeOptionalXmlishFunctionClose(text: string, start: number): number return consumeXmlishFunctionClose(text, start) ?? start; } -function parseXmlishPlainTextToolCallBlockEndAt( - text: string, - start: number, - options?: PlainTextToolCallParseOptions, -): number | null { +function parseXmlishPlainTextToolCallBlockEndAt(text: string, start: number): number | null { const opening = parseXmlishOpening(text, start); if (!opening) { return null; } - const allowedToolNames = options?.allowedToolNames - ? new Set(options.allowedToolNames) - : undefined; - if (allowedToolNames && !allowedToolNames.has(opening.name)) { - return null; - } let cursor = opening.end; let parameterCount = 0; diff --git a/scripts/firecrawl-compare.ts b/scripts/firecrawl-compare.ts index 09f950232903..76e3c6eaa18a 100644 --- a/scripts/firecrawl-compare.ts +++ b/scripts/firecrawl-compare.ts @@ -1,8 +1,8 @@ // Firecrawl Compare script supports OpenClaw repository automation. import { pathToFileURL } from "node:url"; import { fetchFirecrawlContent } from "../extensions/firecrawl/api.ts"; -import { extractReadableContent } from "../src/agents/tools/web-tools.js"; import { formatErrorMessage } from "../src/infra/errors.ts"; +import { extractReadableContent } from "../src/web-fetch/content-extractors.runtime.js"; import { readBoundedResponseText as readBoundedResponseTextWithLimit } from "./lib/bounded-response.ts"; const DEFAULT_URLS = [ diff --git a/scripts/lib/test-group-report.mjs b/scripts/lib/test-group-report.mjs index db60e850ae6d..9454c588cc30 100644 --- a/scripts/lib/test-group-report.mjs +++ b/scripts/lib/test-group-report.mjs @@ -21,9 +21,7 @@ function formatSignedMs(value, digits = 1) { } function formatSignedBytesAsMb(valueBytes) { - return valueBytes === null || valueBytes === undefined - ? "n/a" - : `${valueBytes > 0 ? "+" : ""}${formatBytesAsMb(valueBytes)}`; + return `${valueBytes > 0 ? "+" : ""}${formatBytesAsMb(valueBytes)}`; } /** diff --git a/src/cli/command-format.ts b/src/cli/command-format.ts index 9b8fe988540d..c6d6acce6e0f 100644 --- a/src/cli/command-format.ts +++ b/src/cli/command-format.ts @@ -6,8 +6,7 @@ const CLI_PREFIX_RE = /^(?:pnpm|npm|bunx|npx)\s+openclaw\b|^openclaw\b/; const CONTAINER_FLAG_RE = /(?:^|\s)--container(?:\s|=|$)/; const PROFILE_FLAG_RE = /(?:^|\s)--profile(?:\s|=|$)/; const DEV_FLAG_RE = /(?:^|\s)--dev(?:\s|$)/; -const UPDATE_COMMAND_RE = - /^(?:pnpm|npm|bunx|npx)\s+openclaw\b.*(?:^|\s)update(?:\s|$)|^openclaw\b.*(?:^|\s)update(?:\s|$)/; +const UPDATE_COMMAND_RE = /^(?:(?:pnpm|npm|bunx|npx)\s+openclaw|openclaw)\b.*\supdate(?:\s|$)/; const CONTAINER_HINT_RE = /^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/; /** Add active root options to a displayed command without duplicating explicit flags. */ diff --git a/src/config/io.audit.ts b/src/config/io.audit.ts index 4d5308d01bf0..dbe9355ac329 100644 --- a/src/config/io.audit.ts +++ b/src/config/io.audit.ts @@ -54,10 +54,7 @@ const SECRET_FLAG_NAMES = new Set([ const SECRET_FLAG_SUFFIX_PATTERN = /^--(?:[a-z0-9]+(?:-[a-z0-9]+)*-)?(?:token|secret|password|passwd|api[-_]?key|api[-_]?secret|webhook|credential|bearer|pat|private[-_]?key|recovery[-_]?key|signing[-_]?key|encryption[-_]?key|master[-_]?key|session[-_]?key|gateway[-_]?key|service[-_]?key|hook[-_]?key)$/; -function isSecretFlagName(flagName: string | null): boolean { - if (flagName === null) { - return false; - } +function isSecretFlagName(flagName: string): boolean { if (SECRET_FLAG_NAMES.has(flagName)) { return true; } @@ -65,7 +62,7 @@ function isSecretFlagName(flagName: string | null): boolean { } function parseFlagName(arg: string): string | null { - if (typeof arg !== "string" || !arg.startsWith("--")) { + if (!arg.startsWith("--")) { return null; } const eq = arg.indexOf("="); @@ -88,11 +85,6 @@ export function redactConfigAuditArgv(argv: readonly string[]): string[] { const result: string[] = []; let redactNext = false; for (const current of argv) { - if (typeof current !== "string") { - result.push(current); - redactNext = false; - continue; - } if (redactNext) { redactNext = false; result.push("***"); diff --git a/src/infra/exec-wrapper-trust-plan.ts b/src/infra/exec-wrapper-trust-plan.ts index 57647cb6515e..96c6fca7c817 100644 --- a/src/infra/exec-wrapper-trust-plan.ts +++ b/src/infra/exec-wrapper-trust-plan.ts @@ -42,7 +42,6 @@ function finalizeExecWrapperTrustPlan( policyArgv: string[], wrapperChain: string[], policyBlocked: boolean, - blockedWrapper?: string, ): ExecWrapperTrustPlan { const rawExecutable = argv[0]?.trim() ?? ""; const shellWrapperExecutable = @@ -57,9 +56,6 @@ function finalizeExecWrapperTrustPlan( ? extractBindableShellWrapperInlineCommand(argv) : null, }; - if (blockedWrapper !== undefined) { - plan.blockedWrapper = blockedWrapper; - } return plan; } diff --git a/src/media/parse.ts b/src/media/parse.ts index c6fd58c41f27..20ac25fd5529 100644 --- a/src/media/parse.ts +++ b/src/media/parse.ts @@ -37,7 +37,7 @@ export function normalizeMediaSource(src: string): string { return src.startsWith("file://") ? src.replace("file://", "") : src; } -const TRAILING_SERIALIZED_JSON_AFTER_EXT_RE = /^(.*\.\w{1,10})\\?"(?=[\]},:,]|$).*/s; +const TRAILING_SERIALIZED_JSON_AFTER_EXT_RE = /^(.*\.\w{1,10})\\?"(?=[\]},:]|$).*/s; function cleanCandidate(raw: string) { const stripped = raw.replace(/^[`"'[{(]+/, "").replace(/[`"'\\})\],]+$/, "");