build: enable stricter TypeScript checks

This commit is contained in:
Peter Steinberger
2026-05-11 01:55:04 +01:00
parent 2255140113
commit 6346e792c4
74 changed files with 258 additions and 350 deletions

View File

@@ -6,6 +6,7 @@ Docs: https://docs.openclaw.ai
### Changes ### Changes
- TypeScript: enable stricter compiler checks for implicit returns, side-effect imports, overrides, and unused production code.
- Build: upgrade workspace package management to pnpm 11 and keep Docker, install, update, and release workflows on the pnpm 11 config surface. (#79414) Thanks @altaywtf. - Build: upgrade workspace package management to pnpm 11 and keep Docker, install, update, and release workflows on the pnpm 11 config surface. (#79414) Thanks @altaywtf.
- Models: add provider-level `localService` startup for on-demand local model servers before OpenAI-compatible requests, including one-shot model probes. - Models: add provider-level `localService` startup for on-demand local model servers before OpenAI-compatible requests, including one-shot model probes.
- Agents: trim default system prompt guidance and send-only message tool schemas to reduce prompt tokens while preserving GPT-5 personality guidance. - Agents: trim default system prompt guidance and send-only message tool schemas to reduce prompt tokens while preserving GPT-5 personality guidance.

View File

@@ -1,2 +1,2 @@
5219fe6237bdf573740840ef3c29631a8465abb73dd60128fb94589384ae2a96 plugin-sdk-api-baseline.json c1d16721a00a26fc578878e508e9a4e2190fe2fadd80534873d0b47ef5e4b513 plugin-sdk-api-baseline.json
f63c9723859bb900cf636e5e3fc1349a48563e279ca09e01a7ffafad9efe72f8 plugin-sdk-api-baseline.jsonl cb008db0486c3ba433bfda844a1c2526bb9729afa21f865e0e86f3ad95ac7cfe plugin-sdk-api-baseline.jsonl

View File

@@ -647,19 +647,12 @@ async function handleCodexDiagnosticsFeedback(
text: await previewCodexDiagnosticsFeedbackApproval(deps, ctx, parsed.note), text: await previewCodexDiagnosticsFeedbackApproval(deps, ctx, parsed.note),
}; };
} }
return await requestCodexDiagnosticsFeedbackApproval( return await requestCodexDiagnosticsFeedbackApproval(deps, ctx, parsed.note, commandPrefix);
deps,
ctx,
pluginConfig,
parsed.note,
commandPrefix,
);
} }
async function requestCodexDiagnosticsFeedbackApproval( async function requestCodexDiagnosticsFeedbackApproval(
deps: CodexCommandDeps, deps: CodexCommandDeps,
ctx: PluginCommandContext, ctx: PluginCommandContext,
pluginConfig: unknown,
note: string, note: string,
commandPrefix: string, commandPrefix: string,
): Promise<PluginCommandResult> { ): Promise<PluginCommandResult> {

View File

@@ -111,9 +111,9 @@ class ExecApprovalContainer extends DiscordUiContainer {
} }
class ExecApprovalActionButton extends Button { class ExecApprovalActionButton extends Button {
customId: string; override customId: string;
label: string; override label: string;
style: ButtonStyle; override style: ButtonStyle;
constructor(params: { approvalId: string; descriptor: ExecApprovalActionDescriptor }) { constructor(params: { approvalId: string; descriptor: ExecApprovalActionDescriptor }) {
super(); super();

View File

@@ -77,9 +77,9 @@ function createButtonComponent(params: {
class DynamicButton extends Button { class DynamicButton extends Button {
label = params.spec.label; label = params.spec.label;
customId = customId; customId = customId;
style = style; override style = style;
emoji = params.spec.emoji; override emoji = params.spec.emoji;
disabled = params.spec.disabled ?? false; override disabled = params.spec.disabled ?? false;
} }
if (internalCustomId) { if (internalCustomId) {
return { return {
@@ -137,11 +137,11 @@ function createSelectComponent(params: {
} }
class DynamicStringSelect extends StringSelectMenu { class DynamicStringSelect extends StringSelectMenu {
customId = customId; customId = customId;
options = options; override options = options;
minValues = params.spec.minValues; override minValues = params.spec.minValues;
maxValues = params.spec.maxValues; override maxValues = params.spec.maxValues;
placeholder = params.spec.placeholder; override placeholder = params.spec.placeholder;
disabled = false; override disabled = false;
} }
return { return {
component: new DynamicStringSelect(), component: new DynamicStringSelect(),
@@ -155,10 +155,10 @@ function createSelectComponent(params: {
if (type === "user") { if (type === "user") {
class DynamicUserSelect extends UserSelectMenu { class DynamicUserSelect extends UserSelectMenu {
customId = customId; customId = customId;
minValues = params.spec.minValues; override minValues = params.spec.minValues;
maxValues = params.spec.maxValues; override maxValues = params.spec.maxValues;
placeholder = params.spec.placeholder; override placeholder = params.spec.placeholder;
disabled = false; override disabled = false;
} }
return { return {
component: new DynamicUserSelect(), component: new DynamicUserSelect(),
@@ -168,10 +168,10 @@ function createSelectComponent(params: {
if (type === "role") { if (type === "role") {
class DynamicRoleSelect extends RoleSelectMenu { class DynamicRoleSelect extends RoleSelectMenu {
customId = customId; customId = customId;
minValues = params.spec.minValues; override minValues = params.spec.minValues;
maxValues = params.spec.maxValues; override maxValues = params.spec.maxValues;
placeholder = params.spec.placeholder; override placeholder = params.spec.placeholder;
disabled = false; override disabled = false;
} }
return { return {
component: new DynamicRoleSelect(), component: new DynamicRoleSelect(),
@@ -181,10 +181,10 @@ function createSelectComponent(params: {
if (type === "mentionable") { if (type === "mentionable") {
class DynamicMentionableSelect extends MentionableSelectMenu { class DynamicMentionableSelect extends MentionableSelectMenu {
customId = customId; customId = customId;
minValues = params.spec.minValues; override minValues = params.spec.minValues;
maxValues = params.spec.maxValues; override maxValues = params.spec.maxValues;
placeholder = params.spec.placeholder; override placeholder = params.spec.placeholder;
disabled = false; override disabled = false;
} }
return { return {
component: new DynamicMentionableSelect(), component: new DynamicMentionableSelect(),
@@ -193,10 +193,10 @@ function createSelectComponent(params: {
} }
class DynamicChannelSelect extends ChannelSelectMenu { class DynamicChannelSelect extends ChannelSelectMenu {
customId = customId; customId = customId;
minValues = params.spec.minValues; override minValues = params.spec.minValues;
maxValues = params.spec.maxValues; override maxValues = params.spec.maxValues;
placeholder = params.spec.placeholder; override placeholder = params.spec.placeholder;
disabled = false; override disabled = false;
} }
return { return {
component: new DynamicChannelSelect(), component: new DynamicChannelSelect(),

View File

@@ -26,11 +26,11 @@ function createModalFieldComponent(
if (field.type === "text") { if (field.type === "text") {
class DynamicTextInput extends TextInput { class DynamicTextInput extends TextInput {
customId = field.id; customId = field.id;
style = mapTextInputStyle(field.style); override style = mapTextInputStyle(field.style);
placeholder = field.placeholder; override placeholder = field.placeholder;
required = field.required; override required = field.required;
minLength = field.minLength; override minLength = field.minLength;
maxLength = field.maxLength; override maxLength = field.maxLength;
} }
return new DynamicTextInput(); return new DynamicTextInput();
} }
@@ -38,31 +38,31 @@ function createModalFieldComponent(
const options = field.options ?? []; const options = field.options ?? [];
class DynamicModalSelect extends StringSelectMenu { class DynamicModalSelect extends StringSelectMenu {
customId = field.id; customId = field.id;
options = options; override options = options;
required = field.required; override required = field.required;
minValues = field.minValues; override minValues = field.minValues;
maxValues = field.maxValues; override maxValues = field.maxValues;
placeholder = field.placeholder; override placeholder = field.placeholder;
} }
return new DynamicModalSelect(); return new DynamicModalSelect();
} }
if (field.type === "role-select") { if (field.type === "role-select") {
class DynamicModalRoleSelect extends RoleSelectMenu { class DynamicModalRoleSelect extends RoleSelectMenu {
customId = field.id; customId = field.id;
required = field.required; override required = field.required;
minValues = field.minValues; override minValues = field.minValues;
maxValues = field.maxValues; override maxValues = field.maxValues;
placeholder = field.placeholder; override placeholder = field.placeholder;
} }
return new DynamicModalRoleSelect(); return new DynamicModalRoleSelect();
} }
if (field.type === "user-select") { if (field.type === "user-select") {
class DynamicModalUserSelect extends UserSelectMenu { class DynamicModalUserSelect extends UserSelectMenu {
customId = field.id; customId = field.id;
required = field.required; override required = field.required;
minValues = field.minValues; override minValues = field.minValues;
maxValues = field.maxValues; override maxValues = field.maxValues;
placeholder = field.placeholder; override placeholder = field.placeholder;
} }
return new DynamicModalUserSelect(); return new DynamicModalUserSelect();
} }
@@ -70,29 +70,29 @@ function createModalFieldComponent(
const options = field.options ?? []; const options = field.options ?? [];
class DynamicCheckboxGroup extends CheckboxGroup { class DynamicCheckboxGroup extends CheckboxGroup {
customId = field.id; customId = field.id;
options = options; override options = options;
required = field.required; override required = field.required;
minValues = field.minValues; override minValues = field.minValues;
maxValues = field.maxValues; override maxValues = field.maxValues;
} }
return new DynamicCheckboxGroup(); return new DynamicCheckboxGroup();
} }
const options = field.options ?? []; const options = field.options ?? [];
class DynamicRadioGroup extends RadioGroup { class DynamicRadioGroup extends RadioGroup {
customId = field.id; customId = field.id;
options = options; override options = options;
required = field.required; override required = field.required;
minValues = field.minValues; override minValues = field.minValues;
maxValues = field.maxValues; override maxValues = field.maxValues;
} }
return new DynamicRadioGroup(); return new DynamicRadioGroup();
} }
export class DiscordFormModal extends ModalBase { export class DiscordFormModal extends ModalBase {
title: string; override title: string;
customId: string; override customId: string;
components: Array<Label | TextDisplay>; override components: Array<Label | TextDisplay>;
customIdParser = parseDiscordModalCustomIdForInteractionImpl; override customIdParser = parseDiscordModalCustomIdForInteractionImpl;
constructor(params: { modalId: string; title: string; fields: DiscordModalFieldDefinition[] }) { constructor(params: { modalId: string; title: string; fields: DiscordModalFieldDefinition[] }) {
super(); super();
@@ -101,10 +101,10 @@ export class DiscordFormModal extends ModalBase {
this.components = params.fields.map((field) => { this.components = params.fields.map((field) => {
const component = createModalFieldComponent(field); const component = createModalFieldComponent(field);
class DynamicLabel extends Label { class DynamicLabel extends Label {
label = field.label; override label = field.label;
description = field.description; override description = field.description;
component = component; override component = component;
customId = field.id; override customId = field.id;
} }
return new DynamicLabel(component); return new DynamicLabel(component);
}); });

View File

@@ -34,9 +34,9 @@ function createTestCommand(params: {
}): BaseCommand { }): BaseCommand {
return new (class extends BaseCommand { return new (class extends BaseCommand {
name = params.name; name = params.name;
description = `${params.name} command`; override description = `${params.name} command`;
type = ApplicationCommandType.ChatInput; type = ApplicationCommandType.ChatInput;
guildIds = params.guildIds; override guildIds = params.guildIds;
serializeOptions() { serializeOptions() {
return params.options; return params.options;
} }
@@ -57,7 +57,7 @@ describe("ComponentRegistry", () => {
class WildcardButton extends Button { class WildcardButton extends Button {
label = "button"; label = "button";
customId = "__button_wildcard__"; customId = "__button_wildcard__";
customIdParser = (id: string) => override customIdParser = (id: string) =>
id === this.customId || id.startsWith("occomp:") id === this.customId || id.startsWith("occomp:")
? { key: "*", data: {} } ? { key: "*", data: {} }
: parseCustomId(id); : parseCustomId(id);
@@ -65,7 +65,7 @@ describe("ComponentRegistry", () => {
class WildcardSelect extends StringSelectMenu { class WildcardSelect extends StringSelectMenu {
customId = "__select_wildcard__"; customId = "__select_wildcard__";
options = []; options = [];
customIdParser = (id: string) => override customIdParser = (id: string) =>
id === this.customId || id.startsWith("occomp:") id === this.customId || id.startsWith("occomp:")
? { key: "*", data: {} } ? { key: "*", data: {} }
: parseCustomId(id); : parseCustomId(id);
@@ -89,7 +89,7 @@ describe("ComponentRegistry", () => {
class EncodedButton extends Button { class EncodedButton extends Button {
label = "button"; label = "button";
customId = "encoded:seed=one"; customId = "encoded:seed=one";
customIdParser = (id: string) => ({ override customIdParser = (id: string) => ({
key: id.startsWith("encoded:") ? "encoded" : parseCustomId(id).key, key: id.startsWith("encoded:") ? "encoded" : parseCustomId(id).key,
data: {}, data: {},
}); });

View File

@@ -50,7 +50,7 @@ export abstract class BaseComponent {
} }
export abstract class BaseMessageInteractiveComponent extends BaseComponent { export abstract class BaseMessageInteractiveComponent extends BaseComponent {
readonly isV2 = false; override readonly isV2 = false;
defer: boolean | ConditionalComponentOption = false; defer: boolean | ConditionalComponentOption = false;
ephemeral: boolean | ConditionalComponentOption = false; ephemeral: boolean | ConditionalComponentOption = false;
abstract customId: string; abstract customId: string;

View File

@@ -45,8 +45,8 @@ export abstract class Button extends BaseButton {
export abstract class LinkButton extends BaseButton { export abstract class LinkButton extends BaseButton {
customId = ""; customId = "";
abstract url: string; abstract url: string;
style = ButtonStyle.Link; override style = ButtonStyle.Link;
async run(): Promise<never> { override async run(): Promise<never> {
throw new Error("Link buttons do not run handlers"); throw new Error("Link buttons do not run handlers");
} }
serialize(): APIButtonComponent { serialize(): APIButtonComponent {
@@ -128,7 +128,7 @@ export abstract class ChannelSelectMenu extends AnySelectMenu {
export class Row<T extends BaseMessageInteractiveComponent> extends BaseComponent { export class Row<T extends BaseMessageInteractiveComponent> extends BaseComponent {
readonly type = ComponentType.ActionRow; readonly type = ComponentType.ActionRow;
readonly isV2 = false; override readonly isV2 = false;
components: T[]; components: T[];
constructor(components: T[] = []) { constructor(components: T[] = []) {
super(); super();
@@ -155,7 +155,7 @@ export class Row<T extends BaseMessageInteractiveComponent> extends BaseComponen
export class TextDisplay extends BaseComponent { export class TextDisplay extends BaseComponent {
readonly type = ComponentType.TextDisplay; readonly type = ComponentType.TextDisplay;
readonly isV2 = true; override readonly isV2 = true;
constructor(public content?: string) { constructor(public content?: string) {
super(); super();
} }
@@ -166,7 +166,7 @@ export class TextDisplay extends BaseComponent {
export class Separator extends BaseComponent { export class Separator extends BaseComponent {
readonly type = ComponentType.Separator; readonly type = ComponentType.Separator;
readonly isV2 = true; override readonly isV2 = true;
divider = true; divider = true;
spacing: 1 | 2 | "small" | "large" = "small"; spacing: 1 | 2 | "small" | "large" = "small";
constructor(options?: { spacing?: Separator["spacing"]; divider?: boolean }) { constructor(options?: { spacing?: Separator["spacing"]; divider?: boolean }) {
@@ -185,7 +185,7 @@ export class Separator extends BaseComponent {
export class Thumbnail extends BaseComponent { export class Thumbnail extends BaseComponent {
readonly type = ComponentType.Thumbnail; readonly type = ComponentType.Thumbnail;
readonly isV2 = true; override readonly isV2 = true;
constructor(public url?: string) { constructor(public url?: string) {
super(); super();
} }
@@ -199,7 +199,7 @@ export class Thumbnail extends BaseComponent {
export class Section extends BaseComponent { export class Section extends BaseComponent {
readonly type = ComponentType.Section; readonly type = ComponentType.Section;
readonly isV2 = true; override readonly isV2 = true;
constructor( constructor(
public components: TextDisplay[] = [], public components: TextDisplay[] = [],
public accessory?: Thumbnail | Button | LinkButton, public accessory?: Thumbnail | Button | LinkButton,
@@ -217,7 +217,7 @@ export class Section extends BaseComponent {
export class MediaGallery extends BaseComponent { export class MediaGallery extends BaseComponent {
readonly type = ComponentType.MediaGallery; readonly type = ComponentType.MediaGallery;
readonly isV2 = true; override readonly isV2 = true;
constructor(public items: Array<{ url: string; description?: string; spoiler?: boolean }> = []) { constructor(public items: Array<{ url: string; description?: string; spoiler?: boolean }> = []) {
super(); super();
} }
@@ -235,7 +235,7 @@ export class MediaGallery extends BaseComponent {
export class File extends BaseComponent { export class File extends BaseComponent {
readonly type = ComponentType.File; readonly type = ComponentType.File;
readonly isV2 = true; override readonly isV2 = true;
constructor( constructor(
public file?: `attachment://${string}`, public file?: `attachment://${string}`,
public spoiler = false, public spoiler = false,
@@ -253,7 +253,7 @@ export class File extends BaseComponent {
export class Container extends BaseComponent { export class Container extends BaseComponent {
readonly type = ComponentType.Container; readonly type = ComponentType.Container;
readonly isV2 = true; override readonly isV2 = true;
components: Array< components: Array<
Row<BaseMessageInteractiveComponent> | TextDisplay | Section | MediaGallery | Separator | File Row<BaseMessageInteractiveComponent> | TextDisplay | Section | MediaGallery | Separator | File
>; >;

View File

@@ -53,12 +53,12 @@ class TestGatewayPlugin extends GatewayPlugin {
sockets: FakeSocket[] = []; sockets: FakeSocket[] = [];
connectCalls: boolean[] = []; connectCalls: boolean[] = [];
connect(resume = false): void { override connect(resume = false): void {
this.connectCalls.push(resume); this.connectCalls.push(resume);
super.connect(resume); super.connect(resume);
} }
protected createWebSocket(): never { protected override createWebSocket(): never {
const socket = new FakeSocket(); const socket = new FakeSocket();
this.sockets.push(socket); this.sockets.push(socket);
return socket as never; return socket as never;

View File

@@ -127,7 +127,7 @@ export class GatewayPlugin extends Plugin {
this.heartbeatTimers.firstHeartbeatTimeout = timer; this.heartbeatTimers.firstHeartbeatTimeout = timer;
} }
async registerClient(client: Client): Promise<void> { override async registerClient(client: Client): Promise<void> {
this.client = client; this.client = client;
if (this.options.shard) { if (this.options.shard) {
client.shardId = this.options.shard[0]; client.shardId = this.options.shard[0];

View File

@@ -18,10 +18,10 @@ describe("dispatchInteraction", () => {
await interaction.reply("done"); await interaction.reply("done");
}); });
class DeferredCommand extends Command { class DeferredCommand extends Command {
name = "deferred"; override name = "deferred";
description = "Deferred command"; override description = "Deferred command";
defer = true; override defer = true;
ephemeral = true; override ephemeral = true;
run = run; run = run;
} }
const client = createInternalTestClient([new DeferredCommand()]); const client = createInternalTestClient([new DeferredCommand()]);
@@ -54,9 +54,9 @@ describe("dispatchInteraction", () => {
await interaction.respond([{ name: "alpha", value: "alpha" }]); await interaction.respond([{ name: "alpha", value: "alpha" }]);
}); });
class OptionAutocompleteCommand extends Command { class OptionAutocompleteCommand extends Command {
name = "choose"; override name = "choose";
description = "Choose"; override description = "Choose";
options = [ override options = [
{ {
name: "model", name: "model",
description: "Model", description: "Model",
@@ -105,15 +105,15 @@ describe("dispatchInteraction", () => {
await interaction.reply("joined"); await interaction.reply("joined");
}); });
class JoinCommand extends Command { class JoinCommand extends Command {
name = "join"; override name = "join";
description = "Join"; override description = "Join";
defer = true; override defer = true;
ephemeral = true; override ephemeral = true;
run = run; run = run;
} }
class VoiceCommand extends CommandWithSubcommands { class VoiceCommand extends CommandWithSubcommands {
name = "vc"; override name = "vc";
description = "Voice"; override description = "Voice";
subcommands = [new JoinCommand()]; subcommands = [new JoinCommand()];
} }
const client = createInternalTestClient([new VoiceCommand()]); const client = createInternalTestClient([new VoiceCommand()]);

View File

@@ -286,7 +286,7 @@ export class BaseComponentInteraction extends BaseInteraction {
async update(payload: MessagePayload): Promise<unknown> { async update(payload: MessagePayload): Promise<unknown> {
return await this.callback(InteractionResponseType.UpdateMessage, serializePayload(payload)); return await this.callback(InteractionResponseType.UpdateMessage, serializePayload(payload));
} }
async acknowledge(): Promise<unknown> { override async acknowledge(): Promise<unknown> {
return await this.callback(InteractionResponseType.DeferredMessageUpdate); return await this.callback(InteractionResponseType.DeferredMessageUpdate);
} }
async showModal(modal: Modal): Promise<unknown> { async showModal(modal: Modal): Promise<unknown> {
@@ -323,7 +323,7 @@ export class ModalInteraction extends BaseInteraction {
client, client,
); );
} }
async acknowledge(): Promise<unknown> { override async acknowledge(): Promise<unknown> {
return await this.callback(InteractionResponseType.DeferredMessageUpdate); return await this.callback(InteractionResponseType.DeferredMessageUpdate);
} }
} }

View File

@@ -67,7 +67,7 @@ export class User<IsPartial extends boolean = false> extends Base {
get avatarUrl() { get avatarUrl() {
return this.avatar ? `https://cdn.discordapp.com/avatars/${this.id}/${this.avatar}.png` : null; return this.avatar ? `https://cdn.discordapp.com/avatars/${this.id}/${this.avatar}.png` : null;
} }
toString(): string { override toString(): string {
return `<@${this.id}>`; return `<@${this.id}>`;
} }
async fetch(): Promise<User> { async fetch(): Promise<User> {

View File

@@ -12,7 +12,7 @@ export class VoicePlugin extends Plugin {
readonly adapters = new Map<string, DiscordGatewayAdapterLibraryMethods>(); readonly adapters = new Map<string, DiscordGatewayAdapterLibraryMethods>();
private gatewayPlugin?: GatewayPlugin; private gatewayPlugin?: GatewayPlugin;
registerClient(client: Client): void { override registerClient(client: Client): void {
this.client = client; this.client = client;
this.gatewayPlugin = client.getPlugin<GatewayPlugin>("gateway"); this.gatewayPlugin = client.getPlugin<GatewayPlugin>("gateway");
if (!this.gatewayPlugin) { if (!this.gatewayPlugin) {

View File

@@ -15,10 +15,10 @@ import { dispatchDiscordComponentEvent } from "./agent-components.dispatch.js";
import { dispatchPluginDiscordInteractiveEvent } from "./agent-components.plugin-interactive.js"; import { dispatchPluginDiscordInteractiveEvent } from "./agent-components.plugin-interactive.js";
export class DiscordComponentModal extends Modal { export class DiscordComponentModal extends Modal {
title = "OpenClaw form"; override title = "OpenClaw form";
customId = "__openclaw_discord_component_modal_wildcard__"; override customId = "__openclaw_discord_component_modal_wildcard__";
components = []; override components = [];
customIdParser = parseDiscordModalCustomIdForInteraction; override customIdParser = parseDiscordModalCustomIdForInteraction;
private ctx: AgentComponentContext; private ctx: AgentComponentContext;
constructor(ctx: AgentComponentContext) { constructor(ctx: AgentComponentContext) {

View File

@@ -21,9 +21,9 @@ import {
import { enqueueSystemEvent } from "./agent-components.deps.runtime.js"; import { enqueueSystemEvent } from "./agent-components.deps.runtime.js";
export class AgentComponentButton extends Button { export class AgentComponentButton extends Button {
label = AGENT_BUTTON_KEY; override label = AGENT_BUTTON_KEY;
customId = `${AGENT_BUTTON_KEY}:seed=1`; customId = `${AGENT_BUTTON_KEY}:seed=1`;
style = ButtonStyle.Primary; override style = ButtonStyle.Primary;
private ctx: AgentComponentContext; private ctx: AgentComponentContext;
constructor(ctx: AgentComponentContext) { constructor(ctx: AgentComponentContext) {
@@ -31,7 +31,7 @@ export class AgentComponentButton extends Button {
this.ctx = ctx; this.ctx = ctx;
} }
async run(interaction: ButtonInteraction, data: ComponentData): Promise<void> { override async run(interaction: ButtonInteraction, data: ComponentData): Promise<void> {
const parsed = parseAgentComponentData(data); const parsed = parseAgentComponentData(data);
if (!parsed) { if (!parsed) {
logError("agent button: failed to parse component data"); logError("agent button: failed to parse component data");
@@ -121,7 +121,7 @@ export class AgentSelectMenu extends StringSelectMenu {
this.ctx = ctx; this.ctx = ctx;
} }
async run(interaction: StringSelectMenuInteraction, data: ComponentData): Promise<void> { override async run(interaction: StringSelectMenuInteraction, data: ComponentData): Promise<void> {
const parsed = parseAgentComponentData(data); const parsed = parseAgentComponentData(data);
if (!parsed) { if (!parsed) {
logError("agent select: failed to parse component data"); logError("agent select: failed to parse component data");

View File

@@ -71,7 +71,7 @@ const SELECT_CONTROLS = {
} satisfies Record<string, SelectControlSpec>; } satisfies Record<string, SelectControlSpec>;
class DiscordComponentSelectControl extends BaseMessageInteractiveComponent { class DiscordComponentSelectControl extends BaseMessageInteractiveComponent {
customIdParser = parseDiscordComponentCustomIdForInteraction; override customIdParser = parseDiscordComponentCustomIdForInteraction;
readonly type: ComponentType; readonly type: ComponentType;
readonly customId: string; readonly customId: string;
@@ -91,7 +91,10 @@ class DiscordComponentSelectControl extends BaseMessageInteractiveComponent {
: { type: this.type, custom_id: this.customId }; : { type: this.type, custom_id: this.customId };
} }
async run(interaction: AgentComponentMessageInteraction, data: ComponentData): Promise<void> { override async run(
interaction: AgentComponentMessageInteraction,
data: ComponentData,
): Promise<void> {
await this.handlers.handleComponentEvent({ await this.handlers.handleComponentEvent({
ctx: this.ctx, ctx: this.ctx,
interaction, interaction,
@@ -104,10 +107,10 @@ class DiscordComponentSelectControl extends BaseMessageInteractiveComponent {
} }
class DiscordComponentButton extends Button { class DiscordComponentButton extends Button {
label = "component"; override label = "component";
customId = "__openclaw_discord_component_button_wildcard__"; override customId = "__openclaw_discord_component_button_wildcard__";
style = ButtonStyle.Primary; override style = ButtonStyle.Primary;
customIdParser = parseDiscordComponentCustomIdForInteraction; override customIdParser = parseDiscordComponentCustomIdForInteraction;
constructor( constructor(
private ctx: AgentComponentContext, private ctx: AgentComponentContext,
@@ -116,7 +119,7 @@ class DiscordComponentButton extends Button {
super(); super();
} }
async run(interaction: ButtonInteraction, data: ComponentData): Promise<void> { override async run(interaction: ButtonInteraction, data: ComponentData): Promise<void> {
const parsed = parseDiscordComponentData(data, resolveInteractionCustomId(interaction)); const parsed = parseDiscordComponentData(data, resolveInteractionCustomId(interaction));
if (parsed?.modalId) { if (parsed?.modalId) {
await this.handlers.handleModalTrigger({ await this.handlers.handleModalTrigger({

View File

@@ -68,15 +68,15 @@ function isStructuredApprovalNotFoundError(err: unknown): boolean {
} }
export class ExecApprovalButton extends Button { export class ExecApprovalButton extends Button {
label = "execapproval"; override label = "execapproval";
customId = "execapproval:seed=1"; customId = "execapproval:seed=1";
style = ButtonStyle.Primary; override style = ButtonStyle.Primary;
constructor(private readonly ctx: ExecApprovalButtonContext) { constructor(private readonly ctx: ExecApprovalButtonContext) {
super(); super();
} }
async run(interaction: ButtonInteraction, data: ComponentData): Promise<void> { override async run(interaction: ButtonInteraction, data: ComponentData): Promise<void> {
const parsed = parseExecApprovalData(data); const parsed = parseExecApprovalData(data);
if (!parsed) { if (!parsed) {
try { try {

View File

@@ -143,8 +143,8 @@ function createModelPickerButton(params: DiscordModelPickerButtonOptions): Butto
class DiscordModelPickerButton extends Button { class DiscordModelPickerButton extends Button {
label = params.label; label = params.label;
customId = params.customId; customId = params.customId;
style = params.style ?? ButtonStyle.Secondary; override style = params.style ?? ButtonStyle.Secondary;
disabled = params.disabled ?? false; override disabled = params.disabled ?? false;
} }
return new DiscordModelPickerButton(); return new DiscordModelPickerButton();
} }
@@ -157,11 +157,11 @@ function createModelSelect(params: {
}): StringSelectMenu { }): StringSelectMenu {
class DiscordModelPickerSelect extends StringSelectMenu { class DiscordModelPickerSelect extends StringSelectMenu {
customId = params.customId; customId = params.customId;
options = params.options; override options = params.options;
minValues = 1; override minValues = 1;
maxValues = 1; override maxValues = 1;
placeholder = params.placeholder; override placeholder = params.placeholder;
disabled = params.disabled ?? false; override disabled = params.disabled ?? false;
} }
return new DiscordModelPickerSelect(); return new DiscordModelPickerSelect();
} }

View File

@@ -155,7 +155,7 @@ async function runDiscordCommandArgButton(
class DiscordCommandArgButton extends Button { class DiscordCommandArgButton extends Button {
label: string; label: string;
customId: string; customId: string;
style = ButtonStyle.Secondary; override style = ButtonStyle.Secondary;
constructor( constructor(
params: { params: {
@@ -171,7 +171,7 @@ class DiscordCommandArgButton extends Button {
private params: DiscordCommandArgButtonParams; private params: DiscordCommandArgButtonParams;
async run(interaction: ButtonInteraction, data: ComponentData) { override async run(interaction: ButtonInteraction, data: ComponentData) {
await runDiscordCommandArgButton({ ...this.params, interaction, data }); await runDiscordCommandArgButton({ ...this.params, interaction, data });
} }
} }
@@ -221,7 +221,7 @@ class DiscordCommandArgFallbackButton extends Button {
super(); super();
} }
async run(interaction: ButtonInteraction, data: ComponentData) { override async run(interaction: ButtonInteraction, data: ComponentData) {
await runDiscordCommandArgButton({ ...this.params, interaction, data }); await runDiscordCommandArgButton({ ...this.params, interaction, data });
} }
} }

View File

@@ -443,7 +443,7 @@ class DiscordModelPickerFallbackButton extends Button {
super(); super();
} }
async run(interaction: ButtonInteraction, data: ComponentData) { override async run(interaction: ButtonInteraction, data: ComponentData) {
await runDiscordModelPickerFallback({ ...this.params, interaction, data }); await runDiscordModelPickerFallback({ ...this.params, interaction, data });
} }
} }
@@ -456,7 +456,7 @@ class DiscordModelPickerFallbackSelect extends StringSelectMenu {
super(); super();
} }
async run(interaction: StringSelectMenuInteraction, data: ComponentData) { override async run(interaction: StringSelectMenuInteraction, data: ComponentData) {
await runDiscordModelPickerFallback({ ...this.params, interaction, data }); await runDiscordModelPickerFallback({ ...this.params, interaction, data });
} }
} }

View File

@@ -174,18 +174,18 @@ export function createDiscordNativeCommand(params: {
: undefined; : undefined;
return new (class extends Command { return new (class extends Command {
name = command.name; override name = command.name;
description = truncateDiscordCommandDescription({ override description = truncateDiscordCommandDescription({
value: command.description, value: command.description,
label: `command:${command.name}`, label: `command:${command.name}`,
}); });
descriptionLocalizations = truncateDiscordCommandDescriptionLocalizations({ override descriptionLocalizations = truncateDiscordCommandDescriptionLocalizations({
value: command.descriptionLocalizations, value: command.descriptionLocalizations,
label: `command:${command.name}`, label: `command:${command.name}`,
}); });
defer = false; override defer = false;
ephemeral = ephemeralDefault; override ephemeral = ephemeralDefault;
options = options; override options = options;
async run(interaction: CommandInteraction) { async run(interaction: CommandInteraction) {
const deferred = await safeDiscordInteractionCall("interaction defer", () => const deferred = await safeDiscordInteractionCall("interaction defer", () =>

View File

@@ -152,11 +152,11 @@ export function createDiscordVoiceCommand(params: VoiceCommandContext): CommandW
manager.status().find((entry) => entry.guildId === guildId)?.channelId; manager.status().find((entry) => entry.guildId === guildId)?.channelId;
class JoinCommand extends Command { class JoinCommand extends Command {
name = "join"; override name = "join";
description = "Join a voice channel"; override description = "Join a voice channel";
defer = true; override defer = true;
ephemeral = params.ephemeralDefault; override ephemeral = params.ephemeralDefault;
options: CommandOptions = [ override options: CommandOptions = [
{ {
name: "channel", name: "channel",
description: "Voice channel to join", description: "Voice channel to join",
@@ -211,10 +211,10 @@ export function createDiscordVoiceCommand(params: VoiceCommandContext): CommandW
} }
class LeaveCommand extends Command { class LeaveCommand extends Command {
name = "leave"; override name = "leave";
description = "Leave the current voice channel"; override description = "Leave the current voice channel";
defer = true; override defer = true;
ephemeral = params.ephemeralDefault; override ephemeral = params.ephemeralDefault;
async run(interaction: CommandInteraction) { async run(interaction: CommandInteraction) {
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params); const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
@@ -239,10 +239,10 @@ export function createDiscordVoiceCommand(params: VoiceCommandContext): CommandW
} }
class StatusCommand extends Command { class StatusCommand extends Command {
name = "status"; override name = "status";
description = "Show active voice sessions"; override description = "Show active voice sessions";
defer = true; override defer = true;
ephemeral = params.ephemeralDefault; override ephemeral = params.ephemeralDefault;
async run(interaction: CommandInteraction) { async run(interaction: CommandInteraction) {
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params); const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
@@ -273,8 +273,8 @@ export function createDiscordVoiceCommand(params: VoiceCommandContext): CommandW
} }
return new (class extends CommandWithSubcommands { return new (class extends CommandWithSubcommands {
name = "vc"; override name = "vc";
description = "Voice channel controls"; override description = "Voice channel controls";
subcommands = [new JoinCommand(), new LeaveCommand(), new StatusCommand()]; subcommands = [new JoinCommand(), new LeaveCommand(), new StatusCommand()];
})(); })();
} }

View File

@@ -121,7 +121,6 @@ function cleanBlocksForInsert(blocks: FeishuDocxBlock[]): {
// ============ Core Functions ============ // ============ Core Functions ============
/** Max blocks per documentBlockChildren.create request */ /** Max blocks per documentBlockChildren.create request */
const MAX_BLOCKS_PER_INSERT = 50;
const MAX_CONVERT_RETRY_DEPTH = 8; const MAX_CONVERT_RETRY_DEPTH = 8;
async function convertMarkdown(client: Lark.Client, markdown: string) { async function convertMarkdown(client: Lark.Client, markdown: string) {
@@ -416,26 +415,6 @@ async function chunkedConvertMarkdown(client: Lark.Client, markdown: string) {
return { blocks: allBlocks, firstLevelBlockIds: allRootIds }; return { blocks: allBlocks, firstLevelBlockIds: allRootIds };
} }
/** Insert blocks in batches of MAX_BLOCKS_PER_INSERT to avoid API 400 errors */
async function _chunkedInsertBlocks(
client: Lark.Client,
docToken: string,
blocks: FeishuDocxBlock[],
parentBlockId?: string,
): Promise<{ children: FeishuDocxBlockChild[]; skipped: string[] }> {
const allChildren: FeishuDocxBlockChild[] = [];
const allSkipped: string[] = [];
for (let i = 0; i < blocks.length; i += MAX_BLOCKS_PER_INSERT) {
const batch = blocks.slice(i, i + MAX_BLOCKS_PER_INSERT);
const { children, skipped } = await insertBlocks(client, docToken, batch, parentBlockId);
allChildren.push(...children);
allSkipped.push(...skipped);
}
return { children: allChildren, skipped: allSkipped };
}
type Logger = { info?: (msg: string) => void }; type Logger = { info?: (msg: string) => void };
/** /**

View File

@@ -8,7 +8,6 @@ import {
} from "openclaw/plugin-sdk/provider-stream-shared"; } from "openclaw/plugin-sdk/provider-stream-shared";
import { rewriteCopilotResponsePayloadConnectionBoundIds } from "./connection-bound-ids.js"; import { rewriteCopilotResponsePayloadConnectionBoundIds } from "./connection-bound-ids.js";
type _StreamContext = Parameters<StreamFn>[1];
type StreamOptions = Parameters<StreamFn>[2]; type StreamOptions = Parameters<StreamFn>[2];
function containsCopilotContentType(value: unknown, type: string): boolean { function containsCopilotContentType(value: unknown, type: string): boolean {

View File

@@ -30,9 +30,6 @@ function normalizeUserId(raw?: string | null): string {
return normalizeLowercaseStringOrEmpty(trimmed.replace(/^users\//i, "")); return normalizeLowercaseStringOrEmpty(trimmed.replace(/^users\//i, ""));
} }
type GoogleChatDmPolicy = "open" | "pairing" | "allowlist" | "disabled";
type GoogleChatGroupPolicy = "open" | "allowlist" | "disabled";
const GOOGLECHAT_EMAIL_KIND = "plugin:googlechat-email" as const; const GOOGLECHAT_EMAIL_KIND = "plugin:googlechat-email" as const;
function normalizeEntryValue(raw?: string | null): string { function normalizeEntryValue(raw?: string | null): string {

View File

@@ -9,7 +9,6 @@ import {
async function updateMatrixPins( async function updateMatrixPins(
roomId: string, roomId: string,
messageId: string,
opts: MatrixActionClientOpts, opts: MatrixActionClientOpts,
update: (current: string[]) => string[], update: (current: string[]) => string[],
): Promise<{ pinned: string[] }> { ): Promise<{ pinned: string[] }> {
@@ -27,7 +26,7 @@ export async function pinMatrixMessage(
messageId: string, messageId: string,
opts: MatrixActionClientOpts = {}, opts: MatrixActionClientOpts = {},
): Promise<{ pinned: string[] }> { ): Promise<{ pinned: string[] }> {
return await updateMatrixPins(roomId, messageId, opts, (current) => return await updateMatrixPins(roomId, opts, (current) =>
current.includes(messageId) ? current : [...current, messageId], current.includes(messageId) ? current : [...current, messageId],
); );
} }
@@ -37,7 +36,7 @@ export async function unpinMatrixMessage(
messageId: string, messageId: string,
opts: MatrixActionClientOpts = {}, opts: MatrixActionClientOpts = {},
): Promise<{ pinned: string[] }> { ): Promise<{ pinned: string[] }> {
return await updateMatrixPins(roomId, messageId, opts, (current) => return await updateMatrixPins(roomId, opts, (current) =>
current.filter((id) => id !== messageId), current.filter((id) => id !== messageId),
); );
} }

View File

@@ -161,7 +161,7 @@ export class MatrixVerificationManager {
) {} ) {}
private readRequestValue<T>( private readRequestValue<T>(
request: MatrixVerificationRequestLike, _request: MatrixVerificationRequestLike,
reader: () => T, reader: () => T,
fallback: T, fallback: T,
): T { ): T {

View File

@@ -41,13 +41,6 @@ type StoredMatrixThreadBindingState = {
bindings: MatrixThreadBindingRecord[]; bindings: MatrixThreadBindingRecord[];
}; };
function _normalizeDurationMs(raw: unknown, fallback: number): number {
if (typeof raw !== "number" || !Number.isFinite(raw)) {
return fallback;
}
return Math.max(0, Math.floor(raw));
}
function resolveBindingsPath(params: { function resolveBindingsPath(params: {
auth: MatrixAuth; auth: MatrixAuth;
accountId: string; accountId: string;

View File

@@ -51,8 +51,6 @@ import {
} from "./manager-status-state.js"; } from "./manager-status-state.js";
import { import {
enqueueMemoryTargetedSessionSync, enqueueMemoryTargetedSessionSync,
extractMemoryErrorReason,
isMemoryReadonlyDbError,
runMemorySyncWithReadonlyRecovery, runMemorySyncWithReadonlyRecovery,
type MemoryReadonlyRecoveryState, type MemoryReadonlyRecoveryState,
} from "./manager-sync-control.js"; } from "./manager-sync-control.js";
@@ -94,14 +92,14 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
protected readonly agentId: string; protected readonly agentId: string;
protected readonly workspaceDir: string; protected readonly workspaceDir: string;
protected readonly settings: ResolvedMemorySearchConfig; protected readonly settings: ResolvedMemorySearchConfig;
protected provider: EmbeddingProvider | null; protected override provider: EmbeddingProvider | null;
private readonly requestedProvider: EmbeddingProviderRequest; private readonly requestedProvider: EmbeddingProviderRequest;
private providerInitPromise: Promise<void> | null = null; private providerInitPromise: Promise<void> | null = null;
private providerInitialized = false; private providerInitialized = false;
protected fallbackFrom?: EmbeddingProviderId; protected override fallbackFrom?: EmbeddingProviderId;
protected fallbackReason?: string; protected override fallbackReason?: string;
private providerUnavailableReason?: string; private providerUnavailableReason?: string;
protected providerRuntime?: EmbeddingProviderRuntime; protected override providerRuntime?: EmbeddingProviderRuntime;
protected batch: { protected batch: {
enabled: boolean; enabled: boolean;
wait: boolean; wait: boolean;
@@ -114,8 +112,8 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
protected batchFailureLastProvider?: string; protected batchFailureLastProvider?: string;
protected batchFailureLock: Promise<void> = Promise.resolve(); protected batchFailureLock: Promise<void> = Promise.resolve();
protected db: DatabaseSync; protected db: DatabaseSync;
protected readonly sources: Set<MemorySource>; protected override readonly sources: Set<MemorySource>;
protected providerKey: string; protected override providerKey: string;
protected readonly cache: { enabled: boolean; maxEntries?: number }; protected readonly cache: { enabled: boolean; maxEntries?: number };
protected readonly vector: { protected readonly vector: {
enabled: boolean; enabled: boolean;
@@ -125,23 +123,23 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
loadError?: string; loadError?: string;
dims?: number; dims?: number;
}; };
protected readonly fts: { protected override readonly fts: {
enabled: boolean; enabled: boolean;
available: boolean; available: boolean;
loadError?: string; loadError?: string;
}; };
protected vectorReady: Promise<boolean> | null = null; protected override vectorReady: Promise<boolean> | null = null;
protected watcher: FSWatcher | null = null; protected override watcher: FSWatcher | null = null;
protected watchTimer: NodeJS.Timeout | null = null; protected override watchTimer: NodeJS.Timeout | null = null;
protected sessionWatchTimer: NodeJS.Timeout | null = null; protected override sessionWatchTimer: NodeJS.Timeout | null = null;
protected sessionUnsubscribe: (() => void) | null = null; protected override sessionUnsubscribe: (() => void) | null = null;
protected intervalTimer: NodeJS.Timeout | null = null; protected override intervalTimer: NodeJS.Timeout | null = null;
protected closed = false; protected override closed = false;
protected dirty = false; protected override dirty = false;
protected sessionsDirty = false; protected override sessionsDirty = false;
protected sessionsDirtyFiles = new Set<string>(); protected override sessionsDirtyFiles = new Set<string>();
protected sessionPendingFiles = new Set<string>(); protected override sessionPendingFiles = new Set<string>();
protected sessionDeltas = new Map< protected override sessionDeltas = new Map<
string, string,
{ lastSize: number; pendingBytes: number; pendingMessages: number } { lastSize: number; pendingBytes: number; pendingMessages: number }
>(); >();
@@ -653,14 +651,6 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
); );
} }
private isReadonlyDbError(err: unknown): boolean {
return isMemoryReadonlyDbError(err);
}
private extractErrorReason(err: unknown): string {
return extractMemoryErrorReason(err);
}
private async runSyncWithReadonlyRecovery(params?: { private async runSyncWithReadonlyRecovery(params?: {
reason?: string; reason?: string;
force?: boolean; force?: boolean;

View File

@@ -67,7 +67,6 @@ const MAX_QMD_OUTPUT_CHARS = 200_000;
const NUL_MARKER_RE = /(?:\^@|\\0|\\x00|\\u0000|null\s*byte|nul\s*byte)/i; const NUL_MARKER_RE = /(?:\^@|\\0|\\x00|\\u0000|null\s*byte|nul\s*byte)/i;
const QMD_EMBED_BACKOFF_BASE_MS = 60_000; const QMD_EMBED_BACKOFF_BASE_MS = 60_000;
const QMD_EMBED_BACKOFF_MAX_MS = 60 * 60 * 1000; const QMD_EMBED_BACKOFF_MAX_MS = 60 * 60 * 1000;
const HAN_SCRIPT_RE = /[\u3400-\u9fff]/u;
const QMD_EMBED_LOCK_MIN_WAIT_MS = 15 * 60 * 1000; const QMD_EMBED_LOCK_MIN_WAIT_MS = 15 * 60 * 1000;
const QMD_EMBED_LOCK_RETRY_TEMPLATE = { const QMD_EMBED_LOCK_RETRY_TEMPLATE = {
factor: 1.2, factor: 1.2,
@@ -148,10 +147,6 @@ function getQmdUpdateQueueState(): QmdUpdateQueueState {
})); }));
} }
function _hasHanScript(value: string): boolean {
return HAN_SCRIPT_RE.test(value);
}
function normalizeHanBm25Query(query: string): string { function normalizeHanBm25Query(query: string): string {
const trimmed = query.trim(); const trimmed = query.trim();
// Keep Han/CJK BM25 queries intact so OpenClaw search semantics match direct qmd search. // Keep Han/CJK BM25 queries intact so OpenClaw search semantics match direct qmd search.
@@ -2565,15 +2560,6 @@ export class QmdMemoryManager implements MemorySearchManager {
return `${normalizedName || fallbackName || "file"}${normalizedExt}`; return `${normalizedName || fallbackName || "file"}${normalizedExt}`;
} }
private extractSnippetLines(snippet: string): { startLine: number; endLine: number } {
const headerLines = this.parseSnippetHeaderLines(snippet);
if (headerLines) {
return headerLines;
}
const lines = snippet.split("\n").length;
return { startLine: 1, endLine: lines };
}
private resolveSnippetLines( private resolveSnippetLines(
entry: QmdQueryResult, entry: QmdQueryResult,
snippet: string, snippet: string,

View File

@@ -1,7 +1,6 @@
import type { import type {
AllowlistMatch, AllowlistMatch,
ChannelGroupContext, ChannelGroupContext,
GroupPolicy,
GroupToolPolicyConfig, GroupToolPolicyConfig,
MSTeamsChannelConfig, MSTeamsChannelConfig,
MSTeamsConfig, MSTeamsConfig,

View File

@@ -50,7 +50,7 @@ export default defineBundledChannelEntry({
const account = resolveNostrAccount({ cfg, accountId }); const account = resolveNostrAccount({ cfg, accountId });
return account.profile; return account.profile;
}, },
updateConfigProfile: async (accountId: string, profile: unknown) => { updateConfigProfile: async (_accountId: string, profile: unknown) => {
const runtime = getNostrRuntime(); const runtime = getNostrRuntime();
const cfg = runtime.config.current() as OpenClawConfig; const cfg = runtime.config.current() as OpenClawConfig;

View File

@@ -8,14 +8,6 @@ import { getNostrRuntime } from "./runtime.js";
const STORE_VERSION = 2; const STORE_VERSION = 2;
const PROFILE_STATE_VERSION = 1; const PROFILE_STATE_VERSION = 1;
type _NostrBusStateV1 = {
version: 1;
/** Unix timestamp (seconds) of the last processed event */
lastProcessedAt: number | null;
/** Gateway startup timestamp (seconds) - events before this are old */
gatewayStartedAt: number | null;
};
type NostrBusState = { type NostrBusState = {
version: 2; version: 2;
/** Unix timestamp (seconds) of the last processed event */ /** Unix timestamp (seconds) of the last processed event */

View File

@@ -236,7 +236,7 @@ export class MessageApi {
// ---- Internal ---- // ---- Internal ----
private async sendAndNotify( private async sendAndNotify(
appId: string, _appId: string,
accessToken: string, accessToken: string,
method: string, method: string,
path: string, path: string,

View File

@@ -80,7 +80,7 @@ export class ReconnectState {
const delay = const delay =
customDelay ?? RECONNECT_DELAYS[Math.min(this.attempts, RECONNECT_DELAYS.length - 1)]; customDelay ?? RECONNECT_DELAYS[Math.min(this.attempts, RECONNECT_DELAYS.length - 1)];
this.attempts++; this.attempts++;
this.log?.debug?.(`Reconnecting in ${delay}ms (attempt ${this.attempts})`); this.log?.debug?.(`Reconnecting ${this.accountId} in ${delay}ms (attempt ${this.attempts})`);
return delay; return delay;
} }

View File

@@ -82,7 +82,7 @@ function normalizeExt(ext: string): string | undefined {
return /^[a-z0-9]{1,12}$/.test(trimmed) ? trimmed : undefined; return /^[a-z0-9]{1,12}$/.test(trimmed) ? trimmed : undefined;
} }
function pickAfconvertRecipe(source: string, target: string): string[] | undefined { function pickAfconvertRecipe(_source: string, target: string): string[] | undefined {
// Currently only the MP3->CAF path used by native Messages voice memos. // Currently only the MP3->CAF path used by native Messages voice memos.
if (target === "caf") { if (target === "caf") {
// Opus-in-CAF, mono, 24 kHz. Validated against macOS 15.x Messages.app's // Opus-in-CAF, mono, 24 kHz. Validated against macOS 15.x Messages.app's

View File

@@ -249,10 +249,6 @@ function sortSpeechProvidersForAutoSelection(cfg?: OpenClawConfig) {
}); });
} }
function _resolveRegistryDefaultSpeechProviderId(cfg?: OpenClawConfig): TtsProvider {
return sortSpeechProvidersForAutoSelection(cfg)[0]?.id ?? "";
}
function resolveTtsRuntimeConfig(cfg: OpenClawConfig): OpenClawConfig { function resolveTtsRuntimeConfig(cfg: OpenClawConfig): OpenClawConfig {
return ( return (
selectApplicableRuntimeConfig({ selectApplicableRuntimeConfig({

View File

@@ -404,7 +404,7 @@ export function createTelegramBotCore(
const MAX_RAW_UPDATE_ARRAY = 20; const MAX_RAW_UPDATE_ARRAY = 20;
const stringifyUpdate = (update: unknown) => { const stringifyUpdate = (update: unknown) => {
const seen = new WeakSet(); const seen = new WeakSet();
return JSON.stringify(update ?? null, (key, value) => { return JSON.stringify(update ?? null, (_key, value) => {
if (typeof value === "string" && value.length > MAX_RAW_UPDATE_STRING) { if (typeof value === "string" && value.length > MAX_RAW_UPDATE_STRING) {
return `${value.slice(0, MAX_RAW_UPDATE_STRING)}...`; return `${value.slice(0, MAX_RAW_UPDATE_STRING)}...`;
} }

View File

@@ -934,7 +934,7 @@ export const registerTelegramHandlers = ({
}; };
class TelegramRetryableCallbackError extends Error { class TelegramRetryableCallbackError extends Error {
constructor(public readonly cause: unknown) { constructor(public override readonly cause: unknown) {
super(String(cause)); super(String(cause));
this.name = "TelegramRetryableCallbackError"; this.name = "TelegramRetryableCallbackError";
} }

View File

@@ -1215,7 +1215,6 @@ export const dispatchTelegramMessage = async ({
); );
const segments = split.segments; const segments = split.segments;
const reply = resolveSendableOutboundReplyParts(effectivePayload); const reply = resolveSendableOutboundReplyParts(effectivePayload);
const _hasMedia = reply.hasMedia;
const flushBufferedFinalAnswer = async () => { const flushBufferedFinalAnswer = async () => {
const buffered = const buffered =

View File

@@ -510,12 +510,6 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
const commandBody = isGroup ? stripBotMention(messageText, botShipName) : messageText; const commandBody = isGroup ? stripBotMention(messageText, botShipName) : messageText;
const tlonConversationId = isGroup ? (groupChannel ?? channelNest ?? senderShip) : senderShip; const tlonConversationId = isGroup ? (groupChannel ?? channelNest ?? senderShip) : senderShip;
const rawTurnMessage = {
messageId,
messageText,
timestamp,
};
const ctxPayload = core.channel.turn.buildContext({ const ctxPayload = core.channel.turn.buildContext({
channel: "tlon", channel: "tlon",
accountId: route.accountId, accountId: route.accountId,

View File

@@ -5,15 +5,9 @@ import {
resolveTlonSetupStatusLines, resolveTlonSetupStatusLines,
} from "./setup-core.js"; } from "./setup-core.js";
import { normalizeShip } from "./targets.js"; import { normalizeShip } from "./targets.js";
import { resolveTlonAccount, type TlonResolvedAccount } from "./types.js"; import { resolveTlonAccount } from "./types.js";
import { isBlockedUrbitHostname, validateUrbitBaseUrl } from "./urbit/base-url.js"; import { isBlockedUrbitHostname, validateUrbitBaseUrl } from "./urbit/base-url.js";
const _channel = "tlon" as const;
function _isConfigured(account: TlonResolvedAccount): boolean {
return Boolean(account.ship && account.url && account.code);
}
function parseList(value: string): string[] { function parseList(value: string): string[] {
return value return value
.split(/[\n,;]+/g) .split(/[\n,;]+/g)

View File

@@ -48,7 +48,7 @@ function createLogger(logger?: ChannelLogSink): ChannelLogSink {
export async function resolveTwitchTargets( export async function resolveTwitchTargets(
inputs: string[], inputs: string[],
account: TwitchAccountConfig, account: TwitchAccountConfig,
kind: ChannelResolveKind, _kind: ChannelResolveKind,
logger?: ChannelLogSink, logger?: ChannelLogSink,
): Promise<ChannelResolveResult[]> { ): Promise<ChannelResolveResult[]> {
const log = createLogger(logger); const log = createLogger(logger);

View File

@@ -243,7 +243,7 @@ export async function configureWithEnvToken(
{ {
username, username,
clientId, clientId,
accessToken: "", accessToken: envToken,
enabled: true, enabled: true,
}, },
resolvedAccountId, resolvedAccountId,

View File

@@ -49,7 +49,7 @@ function normalizeXaiSpeechResponseFormat(value: unknown): XaiSpeechResponseForm
} }
function resolveSpeechResponseFormat( function resolveSpeechResponseFormat(
target: SpeechSynthesisTarget, _target: SpeechSynthesisTarget,
configuredFormat?: XaiSpeechResponseFormat, configuredFormat?: XaiSpeechResponseFormat,
): XaiSpeechResponseFormat { ): XaiSpeechResponseFormat {
if (configuredFormat) { if (configuredFormat) {

View File

@@ -161,7 +161,6 @@ type BackgroundTaskContext = {
export class AcpSessionManager { export class AcpSessionManager {
private readonly actorQueue = new SessionActorQueue(); private readonly actorQueue = new SessionActorQueue();
private readonly actorTailBySession = this.actorQueue.getTailMapForTesting();
private readonly runtimeCache = new RuntimeCache(); private readonly runtimeCache = new RuntimeCache();
private readonly activeTurnBySession = new Map<string, ActiveTurnState>(); private readonly activeTurnBySession = new Map<string, ActiveTurnState>();
private readonly turnLatencyStats: TurnLatencyStats = { private readonly turnLatencyStats: TurnLatencyStats = {

View File

@@ -131,7 +131,7 @@ export async function serveAcpGateway(opts: AcpServerOptions = {}): Promise<void
filePath: resolveDefaultAcpEventLedgerPath(process.env), filePath: resolveDefaultAcpEventLedgerPath(process.env),
}); });
const _connection = new AgentSideConnection((conn: AgentSideConnection) => { void new AgentSideConnection((conn: AgentSideConnection) => {
agent = new AcpGatewayAgent(conn, gateway, { ...opts, eventLedger }); agent = new AcpGatewayAgent(conn, gateway, { ...opts, eventLedger });
agent.start(); agent.start();
return agent; return agent;

View File

@@ -7,13 +7,9 @@ import { normalizeOptionalString } from "../../shared/string-coerce.js";
import { CONFIG_DIR, resolveUserPath } from "../../utils.js"; import { CONFIG_DIR, resolveUserPath } from "../../utils.js";
import { resolvePluginSkillDirs } from "./plugin-skills.js"; import { resolvePluginSkillDirs } from "./plugin-skills.js";
import { import {
type SkillsChangeEvent,
bumpSkillsSnapshotVersion, bumpSkillsSnapshotVersion,
getSkillsSnapshotVersion,
registerSkillsChangeListener,
resetSkillsRefreshStateForTest, resetSkillsRefreshStateForTest,
setSkillsChangeListenerErrorHandler, setSkillsChangeListenerErrorHandler,
shouldRefreshSnapshotForVersion,
} from "./refresh-state.js"; } from "./refresh-state.js";
export { export {
bumpSkillsSnapshotVersion, bumpSkillsSnapshotVersion,

View File

@@ -60,11 +60,7 @@ type SessionEntryResolution = {
entry: SessionEntry | undefined; entry: SessionEntry | undefined;
}; };
function resolveStorePathForKey( function resolveStorePathForKey(cfg: OpenClawConfig, parsed?: ParsedAgentSessionKey | null) {
cfg: OpenClawConfig,
key: string,
parsed?: ParsedAgentSessionKey | null,
) {
return resolveStorePath(cfg.session?.store, { return resolveStorePath(cfg.session?.store, {
agentId: parsed?.agentId, agentId: parsed?.agentId,
}); });
@@ -76,7 +72,7 @@ export function resolveSessionEntryForKey(params: {
cache: Map<string, Record<string, SessionEntry>>; cache: Map<string, Record<string, SessionEntry>>;
}): SessionEntryResolution { }): SessionEntryResolution {
const parsed = parseAgentSessionKey(params.key); const parsed = parseAgentSessionKey(params.key);
const storePath = resolveStorePathForKey(params.cfg, params.key, parsed); const storePath = resolveStorePathForKey(params.cfg, parsed);
let store = params.cache.get(storePath); let store = params.cache.get(storePath);
if (!store) { if (!store) {
store = loadSessionStore(storePath); store = loadSessionStore(storePath);

View File

@@ -10,7 +10,7 @@ import { isModelPickerVisibleProvider } from "../../agents/model-picker-visibili
import { listLegacyRuntimeModelProviderAliases } from "../../agents/model-runtime-aliases.js"; import { listLegacyRuntimeModelProviderAliases } from "../../agents/model-runtime-aliases.js";
import { import {
buildModelAliasIndex, buildModelAliasIndex,
modelKey, // Preserve Plugin SDK API baseline source lines after unused import cleanup.
normalizeProviderId, normalizeProviderId,
resolveBareModelDefaultProvider, resolveBareModelDefaultProvider,
resolveDefaultModelForAgent, resolveDefaultModelForAgent,

View File

@@ -95,10 +95,6 @@ const FONT: Record<string, string[]> = {
Z: ["11111", "00001", "00010", "00100", "01000", "10000", "11111"], Z: ["11111", "00001", "00010", "00100", "01000", "10000", "11111"],
}; };
function clampByte(value: number): number {
return Math.max(0, Math.min(255, Math.round(value)));
}
function rgba(r: number, g: number, b: number, a = 255): Rgba { function rgba(r: number, g: number, b: number, a = 255): Rgba {
return { r, g, b, a }; return { r, g, b, a };
} }

View File

@@ -8,7 +8,6 @@ import { defaultRuntime } from "../runtime.js";
import { getTerminalTableWidth, renderTable } from "../terminal/table.js"; import { getTerminalTableWidth, renderTable } from "../terminal/table.js";
import { theme } from "../terminal/theme.js"; import { theme } from "../terminal/theme.js";
import { shortenHomeInString, shortenHomePath } from "../utils.js"; import { shortenHomeInString, shortenHomePath } from "../utils.js";
import { formatCliCommand } from "./command-format.js";
import { formatMissingPluginMessage } from "./error-format.js"; import { formatMissingPluginMessage } from "./error-format.js";
import { quietPluginJsonLogger } from "./plugins-command-helpers.js"; import { quietPluginJsonLogger } from "./plugins-command-helpers.js";

View File

@@ -79,7 +79,7 @@ export type DoctorCompletionOptions = {
* - If no completion at all: prompt to install (with user confirmation) * - If no completion at all: prompt to install (with user confirmation)
*/ */
export async function doctorShellCompletion( export async function doctorShellCompletion(
runtime: RuntimeEnv, _runtime: RuntimeEnv,
prompter: DoctorPrompter, prompter: DoctorPrompter,
options: DoctorCompletionOptions = {}, options: DoctorCompletionOptions = {},
): Promise<void> { ): Promise<void> {

View File

@@ -56,7 +56,7 @@ export async function modelsAliasesAddCommand(
const alias = normalizeAlias(aliasRaw); const alias = normalizeAlias(aliasRaw);
const cfg = await loadModelsConfig({ commandName: "models aliases add", runtime }); const cfg = await loadModelsConfig({ commandName: "models aliases add", runtime });
const resolved = resolveModelTarget({ raw: modelRaw, cfg }); const resolved = resolveModelTarget({ raw: modelRaw, cfg });
const _updated = await updateConfig((cfg) => { await updateConfig((cfg) => {
const modelKey = `${resolved.provider}/${resolved.model}`; const modelKey = `${resolved.provider}/${resolved.model}`;
const nextModels = { ...cfg.agents?.defaults?.models }; const nextModels = { ...cfg.agents?.defaults?.models };
for (const [key, entry] of Object.entries(nextModels)) { for (const [key, entry] of Object.entries(nextModels)) {

View File

@@ -331,7 +331,7 @@ export async function modelsScanCommand(
throw new Error("No image-capable models selected for image model."); throw new Error("No image-capable models selected for image model.");
} }
const _updated = await updateConfig((cfg) => { await updateConfig((cfg) => {
const nextModels = { ...cfg.agents?.defaults?.models }; const nextModels = { ...cfg.agents?.defaults?.models };
for (const entry of selected) { for (const entry of selected) {
if (!nextModels[entry]) { if (!nextModels[entry]) {

View File

@@ -7,7 +7,7 @@ import type { WizardPrompter } from "../wizard/prompts.js";
export async function setupInternalHooks( export async function setupInternalHooks(
cfg: OpenClawConfig, cfg: OpenClawConfig,
runtime: RuntimeEnv, _runtime: RuntimeEnv,
prompter: WizardPrompter, prompter: WizardPrompter,
): Promise<OpenClawConfig> { ): Promise<OpenClawConfig> {
await prompter.note( await prompter.note(

View File

@@ -63,7 +63,7 @@ export class ConfigIncludeError extends Error {
constructor( constructor(
message: string, message: string,
public readonly includePath: string, public readonly includePath: string,
public readonly cause?: Error, public override readonly cause?: Error,
) { ) {
super(message); super(message);
this.name = "ConfigIncludeError"; this.name = "ConfigIncludeError";

View File

@@ -225,11 +225,11 @@ const ModelCompatSchema = z
.optional(); .optional();
type AssertAssignable<_T extends U, U> = true; type AssertAssignable<_T extends U, U> = true;
type _ModelCompatSchemaAssignableToType = AssertAssignable< export type _ModelCompatSchemaAssignableToType = AssertAssignable<
z.infer<typeof ModelCompatSchema>, z.infer<typeof ModelCompatSchema>,
ModelCompatConfig | undefined ModelCompatConfig | undefined
>; >;
type _ModelCompatTypeAssignableToSchema = AssertAssignable< export type _ModelCompatTypeAssignableToSchema = AssertAssignable<
ModelCompatConfig | undefined, ModelCompatConfig | undefined,
z.infer<typeof ModelCompatSchema> z.infer<typeof ModelCompatSchema>
>; >;
@@ -889,11 +889,11 @@ export const ToolsMediaSchema = z
.optional(); .optional();
type ToolsMediaConfigFromSchema = NonNullable<z.infer<typeof ToolsMediaSchema>>; type ToolsMediaConfigFromSchema = NonNullable<z.infer<typeof ToolsMediaSchema>>;
type _ToolsMediaAsyncCompletionSchemaAssignableToType = AssertAssignable< export type _ToolsMediaAsyncCompletionSchemaAssignableToType = AssertAssignable<
ToolsMediaConfigFromSchema["asyncCompletion"], ToolsMediaConfigFromSchema["asyncCompletion"],
MediaToolsConfig["asyncCompletion"] MediaToolsConfig["asyncCompletion"]
>; >;
type _ToolsMediaAsyncCompletionTypeAssignableToSchema = AssertAssignable< export type _ToolsMediaAsyncCompletionTypeAssignableToSchema = AssertAssignable<
MediaToolsConfig["asyncCompletion"], MediaToolsConfig["asyncCompletion"],
ToolsMediaConfigFromSchema["asyncCompletion"] ToolsMediaConfigFromSchema["asyncCompletion"]
>; >;

View File

@@ -83,7 +83,7 @@ export class UnsupportedAttachmentError extends Error {
} }
export class MediaOffloadError extends Error { export class MediaOffloadError extends Error {
readonly cause: unknown; override readonly cause: unknown;
constructor(message: string, options?: ErrorOptions) { constructor(message: string, options?: ErrorOptions) {
super(message, options); super(message, options);
this.name = "MediaOffloadError"; this.name = "MediaOffloadError";

View File

@@ -49,7 +49,7 @@ const DEFAULT_LIVE_PARENT_MODEL = "openai/gpt-5.4";
type LiveAcpAgent = "claude" | "codex" | "droid" | "gemini" | "opencode"; type LiveAcpAgent = "claude" | "codex" | "droid" | "gemini" | "opencode";
class AcpBindSkipError extends Error { class AcpBindSkipError extends Error {
readonly name = "AcpBindSkipError"; override readonly name = "AcpBindSkipError";
} }
function createSlackCurrentConversationBindingRegistry() { function createSlackCurrentConversationBindingRegistry() {

View File

@@ -53,7 +53,7 @@ export type GatewayLockOptions = {
export class GatewayLockError extends Error { export class GatewayLockError extends Error {
constructor( constructor(
message: string, message: string,
public readonly cause?: unknown, public override readonly cause?: unknown,
) { ) {
super(message); super(message);
this.name = "GatewayLockError"; this.name = "GatewayLockError";

View File

@@ -171,8 +171,7 @@ export type VideoGenerationProvider = {
}; };
type AssertAssignable<_Left extends _Right, _Right> = true; type AssertAssignable<_Left extends _Right, _Right> = true;
const _videoGenerationSdkCompat: [
type _VideoGenerationSdkCompat = [
AssertAssignable<GeneratedVideoAsset, CoreGeneratedVideoAsset>, AssertAssignable<GeneratedVideoAsset, CoreGeneratedVideoAsset>,
AssertAssignable<CoreGeneratedVideoAsset, GeneratedVideoAsset>, AssertAssignable<CoreGeneratedVideoAsset, GeneratedVideoAsset>,
AssertAssignable<VideoGenerationAssetRole, CoreVideoGenerationAssetRole>, AssertAssignable<VideoGenerationAssetRole, CoreVideoGenerationAssetRole>,
@@ -213,7 +212,8 @@ type _VideoGenerationSdkCompat = [
AssertAssignable<CoreVideoGenerationSourceAsset, VideoGenerationSourceAsset>, AssertAssignable<CoreVideoGenerationSourceAsset, VideoGenerationSourceAsset>,
AssertAssignable<VideoGenerationTransformCapabilities, CoreVideoGenerationTransformCapabilities>, AssertAssignable<VideoGenerationTransformCapabilities, CoreVideoGenerationTransformCapabilities>,
AssertAssignable<CoreVideoGenerationTransformCapabilities, VideoGenerationTransformCapabilities>, AssertAssignable<CoreVideoGenerationTransformCapabilities, VideoGenerationTransformCapabilities>,
]; ] = [] as never;
void _videoGenerationSdkCompat;
export { export {
DASHSCOPE_WAN_VIDEO_CAPABILITIES, DASHSCOPE_WAN_VIDEO_CAPABILITIES,

View File

@@ -123,7 +123,8 @@ type ReservedSessionEntrySlotKey = Extract<
>; >;
type MissingSessionEntryReservedSlotKeys = Exclude<keyof SessionEntry, ReservedSessionEntrySlotKey>; type MissingSessionEntryReservedSlotKeys = Exclude<keyof SessionEntry, ReservedSessionEntrySlotKey>;
type AssertNever<T extends never> = T; type AssertNever<T extends never> = T;
type _AssertAllSessionEntryKeysAreReserved = AssertNever<MissingSessionEntryReservedSlotKeys>; export type _AssertAllSessionEntryKeysAreReserved =
AssertNever<MissingSessionEntryReservedSlotKeys>;
const SESSION_ENTRY_RESERVED_SLOT_KEYS = new Set<string>(SESSION_ENTRY_RESERVED_SLOT_KEY_LIST); const SESSION_ENTRY_RESERVED_SLOT_KEYS = new Set<string>(SESSION_ENTRY_RESERVED_SLOT_KEY_LIST);
const OBJECT_PROTOTYPE_RESERVED_SLOT_KEYS = new Set<string>([ const OBJECT_PROTOTYPE_RESERVED_SLOT_KEYS = new Set<string>([

View File

@@ -13,7 +13,7 @@ export class CustomEditor extends Editor {
onAltEnter?: () => void; onAltEnter?: () => void;
onAltUp?: () => void; onAltUp?: () => void;
handleInput(data: string): void { override handleInput(data: string): void {
if (matchesKey(data, Key.alt("enter")) && this.onAltEnter) { if (matchesKey(data, Key.alt("enter")) && this.onAltEnter) {
this.onAltEnter(); this.onAltEnter();
return; return;

View File

@@ -1,6 +1,8 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"noUnusedLocals": true,
"noUnusedParameters": true,
"tsBuildInfoFile": ".artifacts/tsgo-cache/core.tsbuildinfo" "tsBuildInfoFile": ".artifacts/tsgo-cache/core.tsbuildinfo"
}, },
"include": ["src/**/*", "ui/**/*", "packages/**/*"], "include": ["src/**/*", "ui/**/*", "packages/**/*"],

View File

@@ -1,6 +1,8 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"noUnusedLocals": true,
"noUnusedParameters": true,
"tsBuildInfoFile": ".artifacts/tsgo-cache/extensions.tsbuildinfo" "tsBuildInfoFile": ".artifacts/tsgo-cache/extensions.tsbuildinfo"
}, },
"include": ["src/**/*.d.ts", "ui/src/**/*.d.ts", "extensions/**/*"], "include": ["src/**/*.d.ts", "ui/src/**/*.d.ts", "extensions/**/*"],

View File

@@ -9,8 +9,11 @@
"lib": ["DOM", "DOM.Iterable", "ES2023", "ScriptHost"], "lib": ["DOM", "DOM.Iterable", "ES2023", "ScriptHost"],
"module": "NodeNext", "module": "NodeNext",
"moduleResolution": "NodeNext", "moduleResolution": "NodeNext",
"noImplicitOverride": true,
"noImplicitReturns": true,
"noEmit": true, "noEmit": true,
"noEmitOnError": true, "noEmitOnError": true,
"noUncheckedSideEffectImports": true,
"outDir": "dist", "outDir": "dist",
"resolveJsonModule": true, "resolveJsonModule": true,
"skipLibCheck": true, "skipLibCheck": true,

View File

@@ -287,8 +287,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal( vi.stubGlobal(
"URL", "URL",
class extends URL { class extends URL {
static createObjectURL = createObjectURL; static override createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL; static override revokeObjectURL = revokeObjectURL;
}, },
); );
const fetchMock = vi.fn((input: string | URL | Request) => { const fetchMock = vi.fn((input: string | URL | Request) => {
@@ -331,8 +331,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal( vi.stubGlobal(
"URL", "URL",
class extends URL { class extends URL {
static createObjectURL = createObjectURL; static override createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL; static override revokeObjectURL = revokeObjectURL;
}, },
); );
const fetchMock = vi.fn((input: string | URL | Request) => { const fetchMock = vi.fn((input: string | URL | Request) => {
@@ -383,8 +383,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal( vi.stubGlobal(
"URL", "URL",
class extends URL { class extends URL {
static createObjectURL = createObjectURL; static override createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL; static override revokeObjectURL = revokeObjectURL;
}, },
); );
const fetchMock = vi.fn((input: string | URL | Request) => { const fetchMock = vi.fn((input: string | URL | Request) => {
@@ -489,8 +489,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal( vi.stubGlobal(
"URL", "URL",
class extends URL { class extends URL {
static createObjectURL = createObjectURL; static override createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL; static override revokeObjectURL = revokeObjectURL;
}, },
); );
const mainRequest = createDeferred<{ avatarUrl?: string }>(); const mainRequest = createDeferred<{ avatarUrl?: string }>();
@@ -1388,8 +1388,8 @@ describe("handleSendChat", () => {
vi.stubGlobal( vi.stubGlobal(
"URL", "URL",
class extends URL { class extends URL {
static createObjectURL = vi.fn(() => "blob:brief"); static override createObjectURL = vi.fn(() => "blob:brief");
static revokeObjectURL = vi.fn(); static override revokeObjectURL = vi.fn();
}, },
); );
const request = vi.fn(async (method: string) => { const request = vi.fn(async (method: string) => {
@@ -1427,8 +1427,8 @@ describe("handleSendChat", () => {
vi.stubGlobal( vi.stubGlobal(
"URL", "URL",
class extends URL { class extends URL {
static createObjectURL = vi.fn(() => "blob:queued"); static override createObjectURL = vi.fn(() => "blob:queued");
static revokeObjectURL = revokeObjectURL; static override revokeObjectURL = revokeObjectURL;
}, },
); );
const file = new File(["%PDF-1.4\n"], "brief.pdf", { type: "application/pdf" }); const file = new File(["%PDF-1.4\n"], "brief.pdf", { type: "application/pdf" });

View File

@@ -618,7 +618,7 @@ export function syncUrlWithTab(host: SettingsHost, tab: Tab, replace: boolean) {
updateBrowserHistory(url, replace); updateBrowserHistory(url, replace);
} }
export function syncUrlWithSessionKey(host: SettingsHost, sessionKey: string, replace: boolean) { export function syncUrlWithSessionKey(_host: SettingsHost, sessionKey: string, replace: boolean) {
const href = typeof window === "undefined" ? undefined : window.location?.href; const href = typeof window === "undefined" ? undefined : window.location?.href;
if (!href) { if (!href) {
return; return;

View File

@@ -150,7 +150,7 @@ function resolveOnboardingMode(): boolean {
} }
export class OpenClawApp extends LitElement { export class OpenClawApp extends LitElement {
private i18nController = new I18nController(this); readonly i18nController = new I18nController(this);
clientInstanceId = generateUUID(); clientInstanceId = generateUUID();
connectGeneration = 0; connectGeneration = 0;
@state() settings: UiSettings = loadSettings(); @state() settings: UiSettings = loadSettings();
@@ -180,8 +180,8 @@ export class OpenClawApp extends LitElement {
@state() lastError: string | null = null; @state() lastError: string | null = null;
@state() lastErrorCode: string | null = null; @state() lastErrorCode: string | null = null;
@state() eventLog: EventLogEntry[] = []; @state() eventLog: EventLogEntry[] = [];
private eventLogBuffer: EventLogEntry[] = []; eventLogBuffer: EventLogEntry[] = [];
private toolStreamSyncTimer: number | null = null; toolStreamSyncTimer: number | null = null;
private sidebarCloseTimer: number | null = null; private sidebarCloseTimer: number | null = null;
@state() assistantName = bootAssistantIdentity.name; @state() assistantName = bootAssistantIdentity.name;
@@ -587,25 +587,25 @@ export class OpenClawApp extends LitElement {
@state() logsAtBottom = true; @state() logsAtBottom = true;
client: GatewayBrowserClient | null = null; client: GatewayBrowserClient | null = null;
private chatScrollFrame: number | null = null; chatScrollFrame: number | null = null;
private chatScrollTimeout: number | null = null; chatScrollTimeout: number | null = null;
private chatLastScrollTop = 0; chatLastScrollTop = 0;
private chatHasAutoScrolled = false; chatHasAutoScrolled = false;
private chatUserNearBottom = true; chatUserNearBottom = true;
@state() chatNewMessagesBelow = false; @state() chatNewMessagesBelow = false;
private nodesPollInterval: number | null = null; nodesPollInterval: number | null = null;
private logsPollInterval: number | null = null; logsPollInterval: number | null = null;
private debugPollInterval: number | null = null; debugPollInterval: number | null = null;
private logsScrollFrame: number | null = null; logsScrollFrame: number | null = null;
private controlUiResponsivenessObserver: { disconnect: () => void } | null = null; controlUiResponsivenessObserver: { disconnect: () => void } | null = null;
private toolStreamById = new Map<string, ToolStreamEntry>(); toolStreamById = new Map<string, ToolStreamEntry>();
private toolStreamOrder: string[] = []; toolStreamOrder: string[] = [];
refreshSessionsAfterChat = new Set<string>(); refreshSessionsAfterChat = new Set<string>();
chatSideResultTerminalRuns = new Set<string>(); chatSideResultTerminalRuns = new Set<string>();
basePath = ""; basePath = "";
private popStateHandler = () => popStateHandler = () =>
onPopStateInternal(this as unknown as Parameters<typeof onPopStateInternal>[0]); onPopStateInternal(this as unknown as Parameters<typeof onPopStateInternal>[0]);
private topbarObserver: ResizeObserver | null = null; topbarObserver: ResizeObserver | null = null;
private globalKeydownHandler = (e: KeyboardEvent) => { private globalKeydownHandler = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.key === "k") { if ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.key === "k") {
e.preventDefault(); e.preventDefault();
@@ -634,11 +634,11 @@ export class OpenClawApp extends LitElement {
this.setChatMobileControlsOpen(false); this.setChatMobileControlsOpen(false);
}; };
createRenderRoot() { override createRenderRoot() {
return this; return this;
} }
connectedCallback() { override connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this.onSlashAction = async (action: string) => { this.onSlashAction = async (action: string) => {
switch (action) { switch (action) {
@@ -668,11 +668,11 @@ export class OpenClawApp extends LitElement {
void this.initWebPushState(); void this.initWebPushState();
} }
protected firstUpdated() { protected override firstUpdated() {
handleFirstUpdated(this as unknown as Parameters<typeof handleFirstUpdated>[0]); handleFirstUpdated(this as unknown as Parameters<typeof handleFirstUpdated>[0]);
} }
disconnectedCallback() { override disconnectedCallback() {
document.removeEventListener("keydown", this.globalKeydownHandler); document.removeEventListener("keydown", this.globalKeydownHandler);
this.nativeBridgeCleanup?.(); this.nativeBridgeCleanup?.();
this.nativeBridgeCleanup = null; this.nativeBridgeCleanup = null;
@@ -691,7 +691,7 @@ export class OpenClawApp extends LitElement {
super.disconnectedCallback(); super.disconnectedCallback();
} }
protected updated(changed: Map<PropertyKey, unknown>) { protected override updated(changed: Map<PropertyKey, unknown>) {
handleUpdated(this as unknown as Parameters<typeof handleUpdated>[0], changed); handleUpdated(this as unknown as Parameters<typeof handleUpdated>[0], changed);
// Some render callbacks assign tab directly while preparing nested panel state. // Some render callbacks assign tab directly while preparing nested panel state.
if (changed.has("tab") && this.tab !== "chat" && this.chatMobileControlsOpen) { if (changed.has("tab") && this.tab !== "chat" && this.chatMobileControlsOpen) {
@@ -1279,7 +1279,7 @@ export class OpenClawApp extends LitElement {
} }
} }
render() { override render() {
return renderApp(this as unknown as AppViewState); return renderApp(this as unknown as AppViewState);
} }
} }

View File

@@ -22,7 +22,7 @@ export class OpenClawModalDialog extends LitElement {
private previouslyFocused: Element | null = null; private previouslyFocused: Element | null = null;
private opened = false; private opened = false;
static styles = css` static override styles = css`
:host { :host {
position: fixed; position: fixed;
inset: 0; inset: 0;

View File

@@ -16,7 +16,7 @@ export class ResizableDivider extends LitElement {
private startRatio = 0; private startRatio = 0;
private activePointerId: number | null = null; private activePointerId: number | null = null;
static styles = css` static override styles = css`
:host { :host {
width: 4px; width: 4px;
cursor: col-resize; cursor: col-resize;
@@ -48,25 +48,25 @@ export class ResizableDivider extends LitElement {
} }
`; `;
render() { override render() {
return nothing; return nothing;
} }
connectedCallback() { override connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this.setStaticAccessibilityAttributes(); this.setStaticAccessibilityAttributes();
this.addEventListener("pointerdown", this.handlePointerDown); this.addEventListener("pointerdown", this.handlePointerDown);
this.addEventListener("keydown", this.handleKeyDown); this.addEventListener("keydown", this.handleKeyDown);
} }
disconnectedCallback() { override disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback();
this.removeEventListener("pointerdown", this.handlePointerDown); this.removeEventListener("pointerdown", this.handlePointerDown);
this.removeEventListener("keydown", this.handleKeyDown); this.removeEventListener("keydown", this.handleKeyDown);
this.stopDragging(); this.stopDragging();
} }
protected updated() { protected override updated() {
this.setAttribute("aria-valuemin", String(this.toAriaValue(this.minRatio))); this.setAttribute("aria-valuemin", String(this.toAriaValue(this.minRatio)));
this.setAttribute("aria-valuemax", String(this.toAriaValue(this.maxRatio))); this.setAttribute("aria-valuemax", String(this.toAriaValue(this.maxRatio)));
this.setAttribute("aria-valuenow", String(this.toAriaValue(this.splitRatio))); this.setAttribute("aria-valuenow", String(this.toAriaValue(this.splitRatio)));