Fix linter errors (#3821)

This commit is contained in:
Chris Estreich 2025-05-21 23:16:43 -07:00 committed by GitHub
parent c6851976fa
commit 39cd50b989
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 220 additions and 152 deletions

6
.prettierignore Normal file
View file

@ -0,0 +1,6 @@
dist
build
out
.next
.venv
pnpm-lock.yaml

View file

@ -2,7 +2,7 @@
"name": "@roo-code/vscode-e2e",
"private": true,
"scripts": {
"lint": "eslint **/*.ts --max-warnings=0",
"lint": "eslint src --ext=ts --max-warnings=0",
"check-types": "tsc --noEmit",
"format": "prettier --write src",
"test:ci": "pnpm --filter roo-cline build:development && pnpm test:run",

View file

@ -8,7 +8,7 @@ import { type RooCodeAPI, Package } from "@roo-code/types"
import { waitFor } from "./utils"
declare global {
var api: RooCodeAPI
let api: RooCodeAPI
}
export async function run() {
@ -29,7 +29,7 @@ export async function run() {
await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`)
await waitFor(() => api.isReady())
// Expose the API to the tests.
// @ts-expect-error - Expose the API to the tests.
globalThis.api = api
// Add all the tests to the runner.

View file

@ -1,12 +1,13 @@
import * as assert from "assert"
import type { ClineMessage } from "@roo-code/types"
import type { RooCodeAPI, ClineMessage } from "@roo-code/types"
import { waitUntilCompleted } from "./utils"
suite("Roo Code Modes", () => {
test("Should handle switching modes correctly", async () => {
const api = globalThis.api
// @ts-expect-error - Expose the API to the tests.
const api = globalThis.api as RooCodeAPI
/**
* Switch modes.
@ -15,7 +16,7 @@ suite("Roo Code Modes", () => {
const switchModesPrompt =
"For each mode (Architect, Ask, Debug) respond with the mode name and what it specializes in after switching to that mode."
let messages: ClineMessage[] = []
const messages: ClineMessage[] = []
const modeSwitches: string[] = []

View file

@ -1,12 +1,13 @@
import * as assert from "assert"
import type { ClineMessage } from "@roo-code/types"
import type { RooCodeAPI, ClineMessage } from "@roo-code/types"
import { sleep, waitFor, waitUntilCompleted } from "./utils"
suite.skip("Roo Code Subtasks", () => {
test("Should handle subtask cancellation and resumption correctly", async () => {
const api = globalThis.api
// @ts-expect-error - Expose the API to the tests.
const api = globalThis.api as RooCodeAPI
const messages: Record<string, ClineMessage[]> = {}

View file

@ -1,12 +1,13 @@
import * as assert from "assert"
import type { ClineMessage } from "@roo-code/types"
import type { RooCodeAPI, ClineMessage } from "@roo-code/types"
import { waitUntilCompleted } from "./utils"
suite("Roo Code Task", () => {
test("Should handle prompt and response correctly", async () => {
const api = globalThis.api
// @ts-expect-error - Expose the API to the tests.
const api = globalThis.api as RooCodeAPI
const messages: ClineMessage[] = []

View file

@ -6,7 +6,7 @@
"main": "./dist/index.js",
"types": "./src/index.ts",
"scripts": {
"lint": "eslint src/**/*.ts --max-warnings=0",
"lint": "eslint src --ext=ts --max-warnings=0",
"check-types": "tsc --noEmit",
"test": "vitest --globals --run",
"build": "tsc",

View file

@ -143,8 +143,8 @@ export function generatePackageJson({
overrideJson,
substitution,
}: {
packageJson: Record<string, any>
overrideJson: Record<string, any>
packageJson: Record<string, any> // eslint-disable-line @typescript-eslint/no-explicit-any
overrideJson: Record<string, any> // eslint-disable-line @typescript-eslint/no-explicit-any
substitution: [string, string]
}) {
const { viewsContainers, views, commands, menus, submenus, configuration } = contributesSchema.parse(contributes)
@ -167,6 +167,7 @@ export function generatePackageJson({
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function transformArrayRecord<T>(obj: Record<string, any[]>, from: string, to: string, props: string[]): T {
return Object.entries(obj).reduce(
(acc, [key, ary]) => ({
@ -187,6 +188,7 @@ function transformArrayRecord<T>(obj: Record<string, any[]>, from: string, to: s
)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function transformArray<T>(arr: any[], from: string, to: string, idProp: string): T[] {
return arr.map(({ [idProp]: id, ...rest }) => ({
[idProp]: id.replace(from, to),
@ -194,6 +196,7 @@ function transformArray<T>(arr: any[], from: string, to: string, idProp: string)
}))
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function transformRecord<T>(obj: Record<string, any>, from: string, to: string): T {
return Object.entries(obj).reduce(
(acc, [key, value]) => ({

View file

@ -1,11 +1,13 @@
import { execSync } from "child_process"
export function getGitSha() {
let gitSha = undefined
let gitSha: string | undefined = undefined
try {
gitSha = execSync("git rev-parse HEAD").toString().trim()
} catch (e) {}
} catch (_e) {
// Do nothing.
}
return gitSha
}

3
pnpm-lock.yaml generated
View file

@ -426,9 +426,6 @@ importers:
ovsx:
specifier: 0.10.2
version: 0.10.2
prettier:
specifier: ^3.4.2
version: 3.5.3
rimraf:
specifier: ^6.0.1
version: 6.0.1

View file

@ -128,7 +128,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
for await (const chunk of stream) {
switch (chunk.type) {
case "message_start":
case "message_start": {
// Tells us cache reads/writes/input/output.
const usage = chunk.message.usage
@ -141,6 +141,7 @@ export class AnthropicHandler extends BaseProvider implements SingleCompletionHa
}
break
}
case "message_delta":
// Tells us stop_reason, stop_sequence, and output tokens
// along the way and at the end of the message.

View file

@ -161,7 +161,10 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
if (this.arnInfo.awsUseCrossRegionInference) this.options.awsUseCrossRegionInference = true
}
this.options.modelTemperature ?? BEDROCK_DEFAULT_TEMPERATURE
if (!this.options.modelTemperature) {
this.options.modelTemperature = BEDROCK_DEFAULT_TEMPERATURE
}
this.costModelConfig = this.getModel()
const clientConfig: BedrockRuntimeClientConfig = {
@ -316,6 +319,7 @@ export class AwsBedrockHandler extends BaseProvider implements SingleCompletionH
error: error instanceof Error ? error : String(error),
})
} finally {
// eslint-disable-next-line no-unsafe-finally
continue
}
}

View file

@ -25,108 +25,103 @@ export class LmStudioHandler extends BaseProvider implements SingleCompletionHan
}
override async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [
{ role: "system", content: systemPrompt },
...convertToOpenAiMessages(messages),
]
const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [
{ role: "system", content: systemPrompt },
...convertToOpenAiMessages(messages),
]
// -------------------------
// Track token usage
// -------------------------
const toContentBlocks = (
blocks: Anthropic.Messages.MessageParam[] | string,
): Anthropic.Messages.ContentBlockParam[] => {
if (typeof blocks === "string") {
return [{ type: "text", text: blocks }]
}
// -------------------------
// Track token usage
// -------------------------
const toContentBlocks = (
blocks: Anthropic.Messages.MessageParam[] | string,
): Anthropic.Messages.ContentBlockParam[] => {
if (typeof blocks === "string") {
return [{ type: "text", text: blocks }]
}
const result: Anthropic.Messages.ContentBlockParam[] = []
for (const msg of blocks) {
if (typeof msg.content === "string") {
result.push({ type: "text", text: msg.content })
} else if (Array.isArray(msg.content)) {
for (const part of msg.content) {
if (part.type === "text") {
result.push({ type: "text", text: part.text })
const result: Anthropic.Messages.ContentBlockParam[] = []
for (const msg of blocks) {
if (typeof msg.content === "string") {
result.push({ type: "text", text: msg.content })
} else if (Array.isArray(msg.content)) {
for (const part of msg.content) {
if (part.type === "text") {
result.push({ type: "text", text: part.text })
}
}
}
}
}
return result
}
let inputTokens = 0
try {
inputTokens = await this.countTokens([
{ type: "text", text: systemPrompt },
...toContentBlocks(messages),
])
} catch (err) {
console.error("[LmStudio] Failed to count input tokens:", err)
inputTokens = 0
}
let assistantText = ""
try {
const params: OpenAI.Chat.ChatCompletionCreateParamsStreaming & { draft_model?: string } = {
model: this.getModel().id,
messages: openAiMessages,
temperature: this.options.modelTemperature ?? LMSTUDIO_DEFAULT_TEMPERATURE,
stream: true,
return result
}
if (this.options.lmStudioSpeculativeDecodingEnabled && this.options.lmStudioDraftModelId) {
params.draft_model = this.options.lmStudioDraftModelId
let inputTokens = 0
try {
inputTokens = await this.countTokens([{ type: "text", text: systemPrompt }, ...toContentBlocks(messages)])
} catch (err) {
console.error("[LmStudio] Failed to count input tokens:", err)
inputTokens = 0
}
const results = await this.client.chat.completions.create(params)
let assistantText = ""
const matcher = new XmlMatcher(
"think",
(chunk) =>
({
type: chunk.matched ? "reasoning" : "text",
text: chunk.data,
}) as const,
)
try {
const params: OpenAI.Chat.ChatCompletionCreateParamsStreaming & { draft_model?: string } = {
model: this.getModel().id,
messages: openAiMessages,
temperature: this.options.modelTemperature ?? LMSTUDIO_DEFAULT_TEMPERATURE,
stream: true,
}
for await (const chunk of results) {
const delta = chunk.choices[0]?.delta
if (this.options.lmStudioSpeculativeDecodingEnabled && this.options.lmStudioDraftModelId) {
params.draft_model = this.options.lmStudioDraftModelId
}
if (delta?.content) {
assistantText += delta.content
for (const processedChunk of matcher.update(delta.content)) {
yield processedChunk
const results = await this.client.chat.completions.create(params)
const matcher = new XmlMatcher(
"think",
(chunk) =>
({
type: chunk.matched ? "reasoning" : "text",
text: chunk.data,
}) as const,
)
for await (const chunk of results) {
const delta = chunk.choices[0]?.delta
if (delta?.content) {
assistantText += delta.content
for (const processedChunk of matcher.update(delta.content)) {
yield processedChunk
}
}
}
}
for (const processedChunk of matcher.final()) {
yield processedChunk
}
for (const processedChunk of matcher.final()) {
yield processedChunk
}
let outputTokens = 0
try {
outputTokens = await this.countTokens([{ type: "text", text: assistantText }])
} catch (err) {
console.error("[LmStudio] Failed to count output tokens:", err)
outputTokens = 0
}
let outputTokens = 0
try {
outputTokens = await this.countTokens([{ type: "text", text: assistantText }])
} catch (err) {
console.error("[LmStudio] Failed to count output tokens:", err)
outputTokens = 0
}
yield {
type: "usage",
inputTokens,
outputTokens,
} as const
} catch (error) {
throw new Error(
"Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Roo Code's prompts.",
)
yield {
type: "usage",
inputTokens,
outputTokens,
} as const
} catch (error) {
throw new Error(
"Please check the LM Studio developer logs to debug what went wrong. You may need to load the model with a larger context length to work with Roo Code's prompts.",
)
}
}
}
override getModel(): { id: string; info: ModelInfo } {
return {

View file

@ -19,6 +19,7 @@ import { DEFAULT_HEADERS, DEEP_SEEK_DEFAULT_TEMPERATURE } from "./constants"
export const AZURE_AI_INFERENCE_PATH = "/models/chat/completions"
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface OpenAiHandlerOptions extends ApiHandlerOptions {}
export class OpenAiHandler extends BaseProvider implements SingleCompletionHandler {

View file

@ -99,9 +99,11 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH
// https://openrouter.ai/docs/features/prompt-caching
if (isCacheAvailable) {
modelId.startsWith("google")
? addGeminiCacheBreakpoints(systemPrompt, openAiMessages)
: addAnthropicCacheBreakpoints(systemPrompt, openAiMessages)
if (modelId.startsWith("google")) {
addGeminiCacheBreakpoints(systemPrompt, openAiMessages)
} else {
addAnthropicCacheBreakpoints(systemPrompt, openAiMessages)
}
}
// https://openrouter.ai/docs/transforms

View file

@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
// node --expose-gc --import tsx src/core/assistant-message/__tests__/parseAssistantMessageBenchmark.ts
import { performance } from "perf_hooks"

View file

@ -1,3 +1,5 @@
/* eslint-disable no-irregular-whitespace */
import { distance } from "fastest-levenshtein"
import { addLineNumbers, everyLineHasLineNumbers, stripLineNumbers } from "../../../integrations/misc/extract-text"

View file

@ -1212,7 +1212,7 @@ export class Task extends EventEmitter<ClineEvents> {
cacheReadTokens += chunk.cacheReadTokens ?? 0
totalCost = chunk.totalCost
break
case "text":
case "text": {
assistantMessage += chunk.text
// Parse raw assistant message into content blocks.
@ -1228,6 +1228,7 @@ export class Task extends EventEmitter<ClineEvents> {
// Present content to user.
presentAssistantMessage(this)
break
}
}
if (this.abort) {

View file

@ -548,6 +548,7 @@ describe("Cline", () => {
// Create a stream that fails on first chunk
const mockError = new Error("API Error")
const mockFailedStream = {
// eslint-disable-next-line require-yield
async *[Symbol.asyncIterator]() {
throw mockError
},
@ -672,6 +673,7 @@ describe("Cline", () => {
// Create a stream that fails on first chunk
const mockError = new Error("API Error")
const mockFailedStream = {
// eslint-disable-next-line require-yield
async *[Symbol.asyncIterator]() {
throw mockError
},

View file

@ -144,7 +144,7 @@ export class ClineProvider extends EventEmitter<ClineProviderEvents> implements
}
// Pop the top Cline instance from the stack.
var cline = this.clineStack.pop()
let cline = this.clineStack.pop()
if (cline) {
console.log(`[subtasks] removing task ${cline.taskId}.${cline.instanceId} from stack`)

View file

@ -1,6 +1,8 @@
import * as esbuild from "esbuild"
import * as path from "path"
import { fileURLToPath } from "url"
import process from "node:process"
import * as console from "node:console"
import { copyPaths, copyWasms, copyLocales, setupLocaleWatcher } from "@roo-code/build"

View file

@ -5,26 +5,31 @@ export default [
...config,
{
rules: {
// TODO: These should be fixed and the rules re-enabled.
"no-regex-spaces": "off",
"no-useless-escape": "off",
"no-empty": "off",
"prefer-const": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": "off",
},
},
{
files: ["i18n/setup.ts", "utils/tts.ts"],
rules: {
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/ban-ts-comment": "off",
},
},
{
files: ["shared/support-prompt.ts"],
files: ["core/assistant-message/presentAssistantMessage.ts", "core/webview/webviewMessageHandler.ts"],
rules: {
"no-prototype-builtins": "off",
"no-case-declarations": "off",
},
},
{
files: ["shared/combineApiRequests.ts", "utils/tts.ts"],
files: ["__mocks__/**/*.js"],
rules: {
"no-empty": "off",
"no-undef": "off",
},
},
{
ignores: ["webview-ui", "out"],
},
]

View file

@ -303,22 +303,23 @@ export class DiffViewProvider {
private async closeAllDiffViews(): Promise<void> {
const closeOps = vscode.window.tabGroups.all
.flatMap(group => group.tabs)
.filter(
tab =>
tab.input instanceof vscode.TabInputTextDiff &&
tab.input.original.scheme === DIFF_VIEW_URI_SCHEME &&
!tab.isDirty
)
.map(tab =>
vscode.window.tabGroups.close(tab).then(
() => undefined,
err => {
console.error(`Failed to close diff tab ${tab.label}`, err);
}
));
await Promise.all(closeOps);
.flatMap((group) => group.tabs)
.filter(
(tab) =>
tab.input instanceof vscode.TabInputTextDiff &&
tab.input.original.scheme === DIFF_VIEW_URI_SCHEME &&
!tab.isDirty,
)
.map((tab) =>
vscode.window.tabGroups.close(tab).then(
() => undefined,
(err) => {
console.error(`Failed to close diff tab ${tab.label}`, err)
},
),
)
await Promise.all(closeOps)
}
private async openDiffEditor(): Promise<vscode.TextEditor> {
@ -425,7 +426,7 @@ export class DiffViewProvider {
return result
}
async reset() : Promise<void> {
async reset(): Promise<void> {
await this.closeAllDiffViews()
this.editType = undefined
this.isEditing = false

View file

@ -47,7 +47,7 @@ export function formatContentBlockToMarkdown(block: Anthropic.Messages.ContentBl
return block.text
case "image":
return `[Image]`
case "tool_use":
case "tool_use": {
let input: string
if (typeof block.input === "object" && block.input !== null) {
input = Object.entries(block.input)
@ -57,7 +57,8 @@ export function formatContentBlockToMarkdown(block: Anthropic.Messages.ContentBl
input = String(block.input)
}
return `[Tool Use: ${block.name}]\n${input}`
case "tool_result":
}
case "tool_result": {
// For now we're not doing tool name lookup since we don't use tools anymore
// const toolName = findToolName(block.tool_use_id, messages)
const toolName = "Tool"
@ -70,6 +71,7 @@ export function formatContentBlockToMarkdown(block: Anthropic.Messages.ContentBl
} else {
return `[${toolName}${block.is_error ? " (Error)" : ""}]`
}
}
default:
return "[Unexpected content type]"
}

View file

@ -11,7 +11,9 @@ export async function extractTextFromFile(filePath: string): Promise<string> {
} catch (error) {
throw new Error(`File not found: ${filePath}`)
}
const fileExtension = path.extname(filePath).toLowerCase()
switch (fileExtension) {
case ".pdf":
return extractTextFromPDF(filePath)
@ -19,13 +21,15 @@ export async function extractTextFromFile(filePath: string): Promise<string> {
return extractTextFromDOCX(filePath)
case ".ipynb":
return extractTextFromIPYNB(filePath)
default:
default: {
const isBinary = await isBinaryFile(filePath).catch(() => false)
if (!isBinary) {
return addLineNumbers(await fs.readFile(filePath, "utf8"))
} else {
throw new Error(`Cannot read text for file type: ${fileExtension}`)
}
}
}
}

View file

@ -392,6 +392,7 @@ export class TerminalProcess extends BaseTerminalProcess {
// should be carefully considered to ensure they only remove control codes and don't
// alter the actual content or behavior of the output stream.
private removeEscapeSequences(str: string): string {
// eslint-disable-next-line no-control-regex
return stripAnsi(str.replace(/\x1b\]633;[^\x07]+\x07/gs, "").replace(/\x1b\]133;[^\x07]+\x07/gs, ""))
}

View file

@ -24,6 +24,7 @@ const hasPwsh = isPowerShellCoreAvailable()
// Define interface for global test environment
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace NodeJS {
interface Global {
__TEST_ENV__: {

View file

@ -1,5 +1,7 @@
import process from "node:process"
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
export default {
preset: "ts-jest",
testEnvironment: "node",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],

View file

@ -318,7 +318,7 @@
}
},
"scripts": {
"lint": "eslint **/*.ts --max-warnings=0",
"lint": "eslint . --ext=ts --max-warnings=0",
"check-types": "tsc --noEmit",
"pretest": "pnpm bundle",
"test": "jest -w=40% && vitest run",
@ -429,7 +429,6 @@
"nock": "^14.0.4",
"npm-run-all2": "^8.0.1",
"ovsx": "0.10.2",
"prettier": "^3.4.2",
"rimraf": "^6.0.1",
"ts-jest": "^29.2.5",
"tsup": "^8.4.0",

View file

@ -12,6 +12,7 @@ export const createPrompt = (template: string, params: PromptParams): string =>
return template.replace(/\${(.*?)}/g, (_, key) => {
if (key === "diagnosticText") {
return generateDiagnosticText(params["diagnostics"] as any[])
// eslint-disable-next-line no-prototype-builtins
} else if (params.hasOwnProperty(key)) {
// Ensure the value is treated as a string for replacement
const value = params[key]

View file

@ -1,6 +1,9 @@
import { jest } from "@jest/globals"
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
import { ExecException } from "child_process"
import { jest } from "@jest/globals"
import { searchCommits, getCommitInfo, getWorkingState } from "../git"
type ExecFunction = (

View file

@ -7,12 +7,31 @@ export default [
rules: {
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": "off",
"react/prop-types": "off",
"react/display-name": "off",
},
},
{
files: ["src/utils/context-mentions.ts", "src/utils/highlighter.ts"],
files: ["src/components/chat/ChatRow.tsx", "src/components/settings/ModelInfoView.tsx"],
rules: {
"prefer-const": "off",
"react/jsx-key": "off",
},
},
{
files: [
"src/components/chat/ChatRow.tsx",
"src/components/chat/ChatView.tsx",
"src/components/chat/BrowserSessionRow.tsx",
"src/components/history/useTaskSearch.ts",
],
rules: {
"no-case-declarations": "off",
},
},
{
files: ["src/__mocks__/**/*.js"],
rules: {
"no-undef": "off",
},
},
]

View file

@ -3,7 +3,7 @@
"private": true,
"type": "module",
"scripts": {
"lint": "eslint src/**/*.{ts,tsx} --max-warnings=0",
"lint": "eslint src --ext=ts,tsx --max-warnings=0",
"check-types": "tsc",
"test": "jest -w=40%",
"format": "prettier --write src",

View file

@ -46,6 +46,7 @@ interface ChatRowProps {
onSuggestionClick?: (answer: string, event?: React.MouseEvent) => void
}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface ChatRowContentProps extends Omit<ChatRowProps, "onHeightChange"> {}
const ChatRow = memo(

View file

@ -62,7 +62,7 @@ const TaskHeader = ({
<div
className={cn(
"rounded-xs p-2.5 flex flex-col gap-1.5 relative z-1 border",
!!isTaskExpanded
isTaskExpanded
? "border-vscode-panel-border text-vscode-foreground"
: "border-vscode-panel-border/80 text-vscode-foreground/80",
)}>

View file

@ -77,7 +77,9 @@ const mockInputRef = React.createRef<HTMLInputElement>()
const mockFocus = jest.fn()
jest.mock("../ChatTextArea", () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const mockReact = require("react")
return {
__esModule: true,
default: mockReact.forwardRef(function MockChatTextArea(

View file

@ -140,6 +140,7 @@ describe("CodeBlock", () => {
it("handles WASM loading errors", async () => {
const mockError = new Error("WASM load failed")
// eslint-disable-next-line @typescript-eslint/no-require-imports
const highlighterUtil = require("../../../utils/highlighter")
highlighterUtil.getHighlighter.mockRejectedValueOnce(mockError)
@ -163,6 +164,7 @@ describe("CodeBlock", () => {
it("verifies highlighter utility is used correctly", async () => {
const code = "const x = 1;"
// eslint-disable-next-line @typescript-eslint/no-require-imports
const highlighterUtil = require("../../../utils/highlighter")
await act(async () => {

View file

@ -19,7 +19,10 @@ export const CopyButton = ({ itemTask }: CopyButtonProps) => {
const tempDiv = document.createElement("div")
tempDiv.innerHTML = itemTask
const text = tempDiv.textContent || tempDiv.innerText || ""
!isCopied && copy(text)
if (!isCopied) {
copy(text)
}
},
[isCopied, copy, itemTask],
)

View file

@ -116,7 +116,6 @@ export const OpenRouter = ({
<Trans
i18nKey="settings:providers.openRouterTransformsText"
components={{
// eslint-disable-next-line jsx-a11y/anchor-has-content
a: <a href="https://openrouter.ai/docs/transforms" />,
}}
/>

View file

@ -38,6 +38,7 @@ const CommandInput = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Input>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
>(({ className, ...props }, ref) => (
// eslint-disable-next-line react/no-unknown-property
<div className="flex items-center border-b border-vscode-dropdown-border px-3" cmdk-input-wrapper="">
<MagnifyingGlassIcon className="mr-2 h-4 w-4 shrink-0 opacity-50" />
<CommandPrimitive.Input

View file

@ -1,5 +1,4 @@
/* eslint-disable no-useless-escape */
/* eslint-disable no-template-curly-in-string */
// npx jest src/utils/__tests__/command-validation.test.ts

View file

@ -255,7 +255,7 @@ export function getContextMenuOptions(
// Convert search results to queryItems format
const searchResultItems = dynamicSearchResults.map((result) => {
// Ensure paths start with / for consistency
let formattedPath = result.path.startsWith("/") ? result.path : `/${result.path}`
const formattedPath = result.path.startsWith("/") ? result.path : `/${result.path}`
// For display purposes, we don't escape spaces in the label or description
const displayPath = formattedPath

View file

@ -128,7 +128,7 @@ const LANGUAGE_LOAD_DELAY = 0
const initialLanguages: BundledLanguage[] = ["shell", "log"]
// Singleton state
let state: {
const state: {
instance: Highlighter | null
instanceInitPromise: Promise<Highlighter> | null
loadedLanguages: Set<ExtendedLanguage>

View file

@ -12,7 +12,7 @@ function getGitSha() {
try {
gitSha = execSync("git rev-parse HEAD").toString().trim()
} catch (_error) {
// NO-OP
// Do nothing.
}
return gitSha