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
- 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.
- 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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -174,18 +174,18 @@ export function createDiscordNativeCommand(params: {
: undefined;
return new (class extends Command {
name = command.name;
description = truncateDiscordCommandDescription({
override name = command.name;
override description = truncateDiscordCommandDescription({
value: command.description,
label: `command:${command.name}`,
});
descriptionLocalizations = truncateDiscordCommandDescriptionLocalizations({
override descriptionLocalizations = truncateDiscordCommandDescriptionLocalizations({
value: command.descriptionLocalizations,
label: `command:${command.name}`,
});
defer = false;
ephemeral = ephemeralDefault;
options = options;
override defer = false;
override ephemeral = ephemeralDefault;
override options = options;
async run(interaction: CommandInteraction) {
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;
class JoinCommand extends Command {
name = "join";
description = "Join a voice channel";
defer = true;
ephemeral = params.ephemeralDefault;
options: CommandOptions = [
override name = "join";
override description = "Join a voice channel";
override defer = true;
override ephemeral = params.ephemeralDefault;
override options: CommandOptions = [
{
name: "channel",
description: "Voice channel to join",
@@ -211,10 +211,10 @@ export function createDiscordVoiceCommand(params: VoiceCommandContext): CommandW
}
class LeaveCommand extends Command {
name = "leave";
description = "Leave the current voice channel";
defer = true;
ephemeral = params.ephemeralDefault;
override name = "leave";
override description = "Leave the current voice channel";
override defer = true;
override ephemeral = params.ephemeralDefault;
async run(interaction: CommandInteraction) {
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
@@ -239,10 +239,10 @@ export function createDiscordVoiceCommand(params: VoiceCommandContext): CommandW
}
class StatusCommand extends Command {
name = "status";
description = "Show active voice sessions";
defer = true;
ephemeral = params.ephemeralDefault;
override name = "status";
override description = "Show active voice sessions";
override defer = true;
override ephemeral = params.ephemeralDefault;
async run(interaction: CommandInteraction) {
const runtimeContext = await resolveVoiceCommandRuntimeContext(interaction, params);
@@ -273,8 +273,8 @@ export function createDiscordVoiceCommand(params: VoiceCommandContext): CommandW
}
return new (class extends CommandWithSubcommands {
name = "vc";
description = "Voice channel controls";
override name = "vc";
override description = "Voice channel controls";
subcommands = [new JoinCommand(), new LeaveCommand(), new StatusCommand()];
})();
}

View File

@@ -121,7 +121,6 @@ function cleanBlocksForInsert(blocks: FeishuDocxBlock[]): {
// ============ Core Functions ============
/** Max blocks per documentBlockChildren.create request */
const MAX_BLOCKS_PER_INSERT = 50;
const MAX_CONVERT_RETRY_DEPTH = 8;
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 };
}
/** 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 };
/**

View File

@@ -8,7 +8,6 @@ import {
} from "openclaw/plugin-sdk/provider-stream-shared";
import { rewriteCopilotResponsePayloadConnectionBoundIds } from "./connection-bound-ids.js";
type _StreamContext = Parameters<StreamFn>[1];
type StreamOptions = Parameters<StreamFn>[2];
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, ""));
}
type GoogleChatDmPolicy = "open" | "pairing" | "allowlist" | "disabled";
type GoogleChatGroupPolicy = "open" | "allowlist" | "disabled";
const GOOGLECHAT_EMAIL_KIND = "plugin:googlechat-email" as const;
function normalizeEntryValue(raw?: string | null): string {

View File

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

View File

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

View File

@@ -41,13 +41,6 @@ type StoredMatrixThreadBindingState = {
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: {
auth: MatrixAuth;
accountId: string;

View File

@@ -51,8 +51,6 @@ import {
} from "./manager-status-state.js";
import {
enqueueMemoryTargetedSessionSync,
extractMemoryErrorReason,
isMemoryReadonlyDbError,
runMemorySyncWithReadonlyRecovery,
type MemoryReadonlyRecoveryState,
} from "./manager-sync-control.js";
@@ -94,14 +92,14 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
protected readonly agentId: string;
protected readonly workspaceDir: string;
protected readonly settings: ResolvedMemorySearchConfig;
protected provider: EmbeddingProvider | null;
protected override provider: EmbeddingProvider | null;
private readonly requestedProvider: EmbeddingProviderRequest;
private providerInitPromise: Promise<void> | null = null;
private providerInitialized = false;
protected fallbackFrom?: EmbeddingProviderId;
protected fallbackReason?: string;
protected override fallbackFrom?: EmbeddingProviderId;
protected override fallbackReason?: string;
private providerUnavailableReason?: string;
protected providerRuntime?: EmbeddingProviderRuntime;
protected override providerRuntime?: EmbeddingProviderRuntime;
protected batch: {
enabled: boolean;
wait: boolean;
@@ -114,8 +112,8 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
protected batchFailureLastProvider?: string;
protected batchFailureLock: Promise<void> = Promise.resolve();
protected db: DatabaseSync;
protected readonly sources: Set<MemorySource>;
protected providerKey: string;
protected override readonly sources: Set<MemorySource>;
protected override providerKey: string;
protected readonly cache: { enabled: boolean; maxEntries?: number };
protected readonly vector: {
enabled: boolean;
@@ -125,23 +123,23 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem
loadError?: string;
dims?: number;
};
protected readonly fts: {
protected override readonly fts: {
enabled: boolean;
available: boolean;
loadError?: string;
};
protected vectorReady: Promise<boolean> | null = null;
protected watcher: FSWatcher | null = null;
protected watchTimer: NodeJS.Timeout | null = null;
protected sessionWatchTimer: NodeJS.Timeout | null = null;
protected sessionUnsubscribe: (() => void) | null = null;
protected intervalTimer: NodeJS.Timeout | null = null;
protected closed = false;
protected dirty = false;
protected sessionsDirty = false;
protected sessionsDirtyFiles = new Set<string>();
protected sessionPendingFiles = new Set<string>();
protected sessionDeltas = new Map<
protected override vectorReady: Promise<boolean> | null = null;
protected override watcher: FSWatcher | null = null;
protected override watchTimer: NodeJS.Timeout | null = null;
protected override sessionWatchTimer: NodeJS.Timeout | null = null;
protected override sessionUnsubscribe: (() => void) | null = null;
protected override intervalTimer: NodeJS.Timeout | null = null;
protected override closed = false;
protected override dirty = false;
protected override sessionsDirty = false;
protected override sessionsDirtyFiles = new Set<string>();
protected override sessionPendingFiles = new Set<string>();
protected override sessionDeltas = new Map<
string,
{ 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?: {
reason?: string;
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 QMD_EMBED_BACKOFF_BASE_MS = 60_000;
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_RETRY_TEMPLATE = {
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 {
const trimmed = query.trim();
// 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}`;
}
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(
entry: QmdQueryResult,
snippet: string,

View File

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

View File

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

View File

@@ -8,14 +8,6 @@ import { getNostrRuntime } from "./runtime.js";
const STORE_VERSION = 2;
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 = {
version: 2;
/** Unix timestamp (seconds) of the last processed event */

View File

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

View File

@@ -80,7 +80,7 @@ export class ReconnectState {
const delay =
customDelay ?? RECONNECT_DELAYS[Math.min(this.attempts, RECONNECT_DELAYS.length - 1)];
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;
}

View File

@@ -82,7 +82,7 @@ function normalizeExt(ext: string): string | 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.
if (target === "caf") {
// 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 {
return (
selectApplicableRuntimeConfig({

View File

@@ -404,7 +404,7 @@ export function createTelegramBotCore(
const MAX_RAW_UPDATE_ARRAY = 20;
const stringifyUpdate = (update: unknown) => {
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) {
return `${value.slice(0, MAX_RAW_UPDATE_STRING)}...`;
}

View File

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

View File

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

View File

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

View File

@@ -5,15 +5,9 @@ import {
resolveTlonSetupStatusLines,
} from "./setup-core.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";
const _channel = "tlon" as const;
function _isConfigured(account: TlonResolvedAccount): boolean {
return Boolean(account.ship && account.url && account.code);
}
function parseList(value: string): string[] {
return value
.split(/[\n,;]+/g)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -60,11 +60,7 @@ type SessionEntryResolution = {
entry: SessionEntry | undefined;
};
function resolveStorePathForKey(
cfg: OpenClawConfig,
key: string,
parsed?: ParsedAgentSessionKey | null,
) {
function resolveStorePathForKey(cfg: OpenClawConfig, parsed?: ParsedAgentSessionKey | null) {
return resolveStorePath(cfg.session?.store, {
agentId: parsed?.agentId,
});
@@ -76,7 +72,7 @@ export function resolveSessionEntryForKey(params: {
cache: Map<string, Record<string, SessionEntry>>;
}): SessionEntryResolution {
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);
if (!store) {
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 {
buildModelAliasIndex,
modelKey,
// Preserve Plugin SDK API baseline source lines after unused import cleanup.
normalizeProviderId,
resolveBareModelDefaultProvider,
resolveDefaultModelForAgent,

View File

@@ -95,10 +95,6 @@ const FONT: Record<string, string[]> = {
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 {
return { r, g, b, a };
}

View File

@@ -8,7 +8,6 @@ import { defaultRuntime } from "../runtime.js";
import { getTerminalTableWidth, renderTable } from "../terminal/table.js";
import { theme } from "../terminal/theme.js";
import { shortenHomeInString, shortenHomePath } from "../utils.js";
import { formatCliCommand } from "./command-format.js";
import { formatMissingPluginMessage } from "./error-format.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)
*/
export async function doctorShellCompletion(
runtime: RuntimeEnv,
_runtime: RuntimeEnv,
prompter: DoctorPrompter,
options: DoctorCompletionOptions = {},
): Promise<void> {

View File

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

View File

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

View File

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

View File

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

View File

@@ -83,7 +83,7 @@ export class UnsupportedAttachmentError extends Error {
}
export class MediaOffloadError extends Error {
readonly cause: unknown;
override readonly cause: unknown;
constructor(message: string, options?: ErrorOptions) {
super(message, options);
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";
class AcpBindSkipError extends Error {
readonly name = "AcpBindSkipError";
override readonly name = "AcpBindSkipError";
}
function createSlackCurrentConversationBindingRegistry() {

View File

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

View File

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

View File

@@ -123,7 +123,8 @@ type ReservedSessionEntrySlotKey = Extract<
>;
type MissingSessionEntryReservedSlotKeys = Exclude<keyof SessionEntry, ReservedSessionEntrySlotKey>;
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 OBJECT_PROTOTYPE_RESERVED_SLOT_KEYS = new Set<string>([

View File

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

View File

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

View File

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

View File

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

View File

@@ -287,8 +287,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal(
"URL",
class extends URL {
static createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL;
static override createObjectURL = createObjectURL;
static override revokeObjectURL = revokeObjectURL;
},
);
const fetchMock = vi.fn((input: string | URL | Request) => {
@@ -331,8 +331,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal(
"URL",
class extends URL {
static createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL;
static override createObjectURL = createObjectURL;
static override revokeObjectURL = revokeObjectURL;
},
);
const fetchMock = vi.fn((input: string | URL | Request) => {
@@ -383,8 +383,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal(
"URL",
class extends URL {
static createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL;
static override createObjectURL = createObjectURL;
static override revokeObjectURL = revokeObjectURL;
},
);
const fetchMock = vi.fn((input: string | URL | Request) => {
@@ -489,8 +489,8 @@ describe("refreshChatAvatar", () => {
vi.stubGlobal(
"URL",
class extends URL {
static createObjectURL = createObjectURL;
static revokeObjectURL = revokeObjectURL;
static override createObjectURL = createObjectURL;
static override revokeObjectURL = revokeObjectURL;
},
);
const mainRequest = createDeferred<{ avatarUrl?: string }>();
@@ -1388,8 +1388,8 @@ describe("handleSendChat", () => {
vi.stubGlobal(
"URL",
class extends URL {
static createObjectURL = vi.fn(() => "blob:brief");
static revokeObjectURL = vi.fn();
static override createObjectURL = vi.fn(() => "blob:brief");
static override revokeObjectURL = vi.fn();
},
);
const request = vi.fn(async (method: string) => {
@@ -1427,8 +1427,8 @@ describe("handleSendChat", () => {
vi.stubGlobal(
"URL",
class extends URL {
static createObjectURL = vi.fn(() => "blob:queued");
static revokeObjectURL = revokeObjectURL;
static override createObjectURL = vi.fn(() => "blob:queued");
static override revokeObjectURL = revokeObjectURL;
},
);
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);
}
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;
if (!href) {
return;

View File

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

View File

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

View File

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