From c31d16f78d6cde752b5092ff3fbc231992bc5352 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Sun, 19 Oct 2025 15:21:33 +0200 Subject: [PATCH 01/14] reimplement #138 --- apps/vscode-extension/src/diagnostics.ts | 94 ++++++++++++++++++ apps/vscode-extension/src/extension.ts | 98 ++----------------- apps/vscode-extension/src/logger.ts | 91 +++++++++++++++++ .../src/provider/hoverProvider.ts | 2 +- .../src/provider/selectedTextHoverProvider.ts | 10 +- .../vscode-extension/src/provider/uriStore.ts | 4 +- 6 files changed, 204 insertions(+), 95 deletions(-) create mode 100644 apps/vscode-extension/src/diagnostics.ts create mode 100644 apps/vscode-extension/src/logger.ts diff --git a/apps/vscode-extension/src/diagnostics.ts b/apps/vscode-extension/src/diagnostics.ts new file mode 100644 index 0000000..18c7354 --- /dev/null +++ b/apps/vscode-extension/src/diagnostics.ts @@ -0,0 +1,94 @@ +import { has } from "@pretty-ts-errors/utils"; +import { formatDiagnostic } from "@pretty-ts-errors/vscode-formatter"; +import { + ExtensionContext, + languages, + MarkdownString, + Range, + window, + Uri, +} from "vscode"; +import { createConverter } from "vscode-languageclient/lib/common/codeConverter"; +import { hoverProvider } from "./provider/hoverProvider"; +import { uriStore } from "./provider/uriStore"; + +const cache = new Map(); +const CACHE_SIZE_MAX = 100; +const supportedDiagnosticSources = [ + "ts", + "ts-plugin", + "deno-ts", + "js", + "glint", +]; +const registeredLanguages = new Set(); + +export function registerOnDidChangeDiagnostics(context: ExtensionContext) { + const converter = createConverter(); + context.subscriptions.push( + languages.onDidChangeDiagnostics(async (e) => { + e.uris.forEach((uri) => { + const diagnostics = languages.getDiagnostics(uri); + const supportedDiagnostics = diagnostics.filter( + (diagnostic) => + diagnostic.source && + has(supportedDiagnosticSources, diagnostic.source) + ); + + const items: { + range: Range; + contents: MarkdownString[]; + }[] = supportedDiagnostics.map((diagnostic) => { + // formatDiagnostic converts message based on LSP Diagnostic type, not VSCode Diagnostic type, so it can be used in other IDEs. + // Here we convert VSCode Diagnostic to LSP Diagnostic to make formatDiagnostic recognize it. + let formattedMessage = cache.get(diagnostic.message); + + if (!formattedMessage) { + const markdownString = new MarkdownString( + formatDiagnostic(converter.asDiagnostic(diagnostic)) + ); + + markdownString.isTrusted = true; + markdownString.supportHtml = true; + + formattedMessage = markdownString; + cache.set(diagnostic.message, formattedMessage); + + if (cache.size > CACHE_SIZE_MAX) { + const firstCacheKey = cache.keys().next().value; + cache.delete(firstCacheKey); + } + } + + return { + range: diagnostic.range, + contents: [formattedMessage], + }; + }); + + uriStore.set(uri.fsPath, items); + + if (items.length > 0) { + ensureHoverProviderIsRegistered(uri, context); + } + }); + }) + ); +} + +function ensureHoverProviderIsRegistered(uri: Uri, context: ExtensionContext) { + const editor = window.visibleTextEditors.find( + (editor) => editor.document.uri.toString() === uri.toString() + ); + if (editor && !registeredLanguages.has(editor.document.languageId)) { + registeredLanguages.add(editor.document.languageId); + context.subscriptions.push( + languages.registerHoverProvider( + { + language: editor.document.languageId, + }, + hoverProvider + ) + ); + } +} diff --git a/apps/vscode-extension/src/extension.ts b/apps/vscode-extension/src/extension.ts index 9991f9f..d8b4dac 100644 --- a/apps/vscode-extension/src/extension.ts +++ b/apps/vscode-extension/src/extension.ts @@ -1,95 +1,15 @@ -import { has } from "@pretty-ts-errors/utils"; -import { formatDiagnostic } from "@pretty-ts-errors/vscode-formatter"; -import { - ExtensionContext, - languages, - MarkdownString, - Range, - window, -} from "vscode"; -import { createConverter } from "vscode-languageclient/lib/common/codeConverter"; -import { hoverProvider } from "./provider/hoverProvider"; +import { ExtensionContext } from "vscode"; import { registerSelectedTextHoverProvider } from "./provider/selectedTextHoverProvider"; -import { uriStore } from "./provider/uriStore"; - -const cache = new Map(); +import { registerOnDidChangeDiagnostics } from "./diagnostics"; +import { logger } from "./logger"; export function activate(context: ExtensionContext) { - const registeredLanguages = new Set(); - const converter = createConverter(); - + logger.info("activating"); + context.subscriptions.push(logger); registerSelectedTextHoverProvider(context); + registerOnDidChangeDiagnostics(context); +} - context.subscriptions.push( - languages.onDidChangeDiagnostics(async (e) => { - e.uris.forEach((uri) => { - const diagnostics = languages.getDiagnostics(uri); - - const items: { - range: Range; - contents: MarkdownString[]; - }[] = []; - - let hasTsDiagnostic = false; - - diagnostics - .filter((diagnostic) => - diagnostic.source - ? has( - ["ts", "ts-plugin", "deno-ts", "js", "glint"], - diagnostic.source - ) - : false - ) - .forEach(async (diagnostic) => { - // formatDiagnostic converts message based on LSP Diagnostic type, not VSCode Diagnostic type, so it can be used in other IDEs. - // Here we convert VSCode Diagnostic to LSP Diagnostic to make formatDiagnostic recognize it. - let formattedMessage = cache.get(diagnostic.message); - - if (!formattedMessage) { - const markdownString = new MarkdownString( - formatDiagnostic(converter.asDiagnostic(diagnostic)) - ); - - markdownString.isTrusted = true; - markdownString.supportHtml = true; - - formattedMessage = markdownString; - cache.set(diagnostic.message, formattedMessage); - - if (cache.size > 100) { - const firstCacheKey = cache.keys().next().value; - cache.delete(firstCacheKey); - } - } - - items.push({ - range: diagnostic.range, - contents: [formattedMessage], - }); - - hasTsDiagnostic = true; - }); - - uriStore[uri.fsPath] = items; - - if (hasTsDiagnostic) { - const editor = window.visibleTextEditors.find( - (editor) => editor.document.uri.toString() === uri.toString() - ); - if (editor && !registeredLanguages.has(editor.document.languageId)) { - registeredLanguages.add(editor.document.languageId); - context.subscriptions.push( - languages.registerHoverProvider( - { - language: editor.document.languageId, - }, - hoverProvider - ) - ); - } - } - }); - }) - ); +export function deactivate() { + logger.info("deactivating"); } diff --git a/apps/vscode-extension/src/logger.ts b/apps/vscode-extension/src/logger.ts new file mode 100644 index 0000000..e70541a --- /dev/null +++ b/apps/vscode-extension/src/logger.ts @@ -0,0 +1,91 @@ +import { LogOutputChannel, window } from "vscode"; + +let instance: null | LogOutputChannel = null; + +function getLogger(): LogOutputChannel { + if (instance !== null) { + return instance; + } + instance = window.createOutputChannel("Pretty TypeScript Errors", { + log: true, + }); + return instance; +} + +function info(...args: Parameters) { + getLogger().info(...args); +} + +function trace(...args: Parameters) { + getLogger().trace(...args); +} + +function debug(...args: Parameters) { + getLogger().debug(...args); +} +function warn(...args: Parameters) { + getLogger().warn(...args); +} + +function error(...args: Parameters) { + getLogger().error(...args); +} + +type LogLevel = "info" | "trace" | "debug" | "warn" | "error"; + +const defaultThresholds: Record = { + error: 5000, + warn: 1000, + info: 100, + debug: 50, + trace: 0, +}; + +/** + * Both in the browser and Node >= 16 (vscode 1.77 has node >= 16) have `performance` available as a global + * But `@types/node` is missing its global declaration, this fixes the type error we get from using it + */ +declare const performance: import("perf_hooks").Performance; + +/** + * Measures the time it took to run `task` and reports it to the `logger` based on `logLevelThresholds`. + * + * NOTE: supports synchronous `task`s only + * @see {@link defaultThresholds} for the default thresholds + */ +function measure( + name: string, + task: () => T, + logLevelThresholds: Partial> = {} +): T { + const start = performance.now(); + const result = task(); + const end = performance.now(); + const duration = end - start; + logLevelThresholds = Object.assign({}, defaultThresholds, logLevelThresholds); + const thresholds = Object.entries(logLevelThresholds) as [LogLevel, number][]; + // sort thresholds from high to low + // { info: 100, warn: 1000, trace: 0 } => [[warn, 1000], [info, 100], [trace, 0]] + thresholds.sort(([_a, a], [_b, b]) => b - a); + const level: LogLevel = + thresholds.find(([_, threshold]) => duration > threshold)?.[0] || "trace"; + getLogger()[level](`${name} took ${duration.toFixed(3)}ms`); + return result; +} + +function dispose() { + if (instance !== null) { + instance.dispose(); + instance = null; + } +} + +export const logger = { + trace, + debug, + info, + warn, + error, + measure, + dispose, +}; diff --git a/apps/vscode-extension/src/provider/hoverProvider.ts b/apps/vscode-extension/src/provider/hoverProvider.ts index 9662fff..2882bce 100644 --- a/apps/vscode-extension/src/provider/hoverProvider.ts +++ b/apps/vscode-extension/src/provider/hoverProvider.ts @@ -3,7 +3,7 @@ import { uriStore } from "./uriStore"; export const hoverProvider: HoverProvider = { provideHover(document, position, _token) { - const itemsInUriStore = uriStore[document.uri.fsPath]; + const itemsInUriStore = uriStore.get(document.uri.fsPath); if (!itemsInUriStore) { return null; diff --git a/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts b/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts index 3209804..19bb39e 100644 --- a/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts +++ b/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts @@ -14,12 +14,11 @@ import { createConverter } from "vscode-languageclient/lib/common/codeConverter" * It format selected text and help test things visually easier. */ export function registerSelectedTextHoverProvider(context: ExtensionContext) { - const converter = createConverter(); - if (context.extensionMode !== ExtensionMode.Development) { return; } + const converter = createConverter(); context.subscriptions.push( languages.registerHoverProvider( { @@ -29,6 +28,11 @@ export function registerSelectedTextHoverProvider(context: ExtensionContext) { { provideHover(document, position) { const editor = window.activeTextEditor; + + if (!editor) { + return; + } + const range = document.getWordRangeAtPosition(position); const message = editor ? document.getText(editor.selection) : ""; @@ -61,7 +65,7 @@ export function registerSelectedTextHoverProvider(context: ExtensionContext) { ); } -const debugHoverHeader = d/*html*/ ` +const debugHoverHeader = d/*html*/ ` Formatted selected text (debug only) diff --git a/apps/vscode-extension/src/provider/uriStore.ts b/apps/vscode-extension/src/provider/uriStore.ts index ec87bcc..5b1dffa 100644 --- a/apps/vscode-extension/src/provider/uriStore.ts +++ b/apps/vscode-extension/src/provider/uriStore.ts @@ -1,9 +1,9 @@ import { MarkdownString, Range, Uri } from "vscode"; -export const uriStore: Record< +export const uriStore = new Map< Uri["path"], { range: Range; contents: MarkdownString[]; }[] -> = {}; +>(); From 9c4a6e1272ecef38935e7640dc66d2c78d7f5138 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Tue, 30 Dec 2025 16:08:19 +0100 Subject: [PATCH 02/14] document diagnostics.ts and the store with some comments and links --- apps/vscode-extension/src/diagnostics.ts | 127 +++++++++++++----- .../src/formattedDiagnosticsStore.ts | 18 +++ .../src/provider/hoverProvider.ts | 4 +- .../src/provider/selectedTextHoverProvider.ts | 6 +- .../provider/textDocumentContentProvider.ts | 4 +- .../vscode-extension/src/provider/uriStore.ts | 9 -- .../src/provider/webviewViewProvider.ts | 13 +- 7 files changed, 122 insertions(+), 59 deletions(-) create mode 100644 apps/vscode-extension/src/formattedDiagnosticsStore.ts delete mode 100644 apps/vscode-extension/src/provider/uriStore.ts diff --git a/apps/vscode-extension/src/diagnostics.ts b/apps/vscode-extension/src/diagnostics.ts index 18c7354..4e64c70 100644 --- a/apps/vscode-extension/src/diagnostics.ts +++ b/apps/vscode-extension/src/diagnostics.ts @@ -4,16 +4,23 @@ import { ExtensionContext, languages, MarkdownString, - Range, window, Uri, + type Diagnostic, } from "vscode"; -import { createConverter } from "vscode-languageclient/lib/common/codeConverter"; +import { + createConverter, + type Converter, +} from "vscode-languageclient/lib/common/codeConverter"; import { hoverProvider } from "./provider/hoverProvider"; -import { uriStore } from "./provider/uriStore"; +import { + formattedDiagnosticsStore, + type FormattedDiagnostic, +} from "./formattedDiagnosticsStore"; -const cache = new Map(); -const CACHE_SIZE_MAX = 100; +/** + * The list of diagnostic sources that pretty-ts-errors supports + */ const supportedDiagnosticSources = [ "ts", "ts-plugin", @@ -21,7 +28,6 @@ const supportedDiagnosticSources = [ "js", "glint", ]; -const registeredLanguages = new Set(); export function registerOnDidChangeDiagnostics(context: ExtensionContext) { const converter = createConverter(); @@ -35,38 +41,14 @@ export function registerOnDidChangeDiagnostics(context: ExtensionContext) { has(supportedDiagnosticSources, diagnostic.source) ); - const items: { - range: Range; - contents: MarkdownString[]; - }[] = supportedDiagnostics.map((diagnostic) => { - // formatDiagnostic converts message based on LSP Diagnostic type, not VSCode Diagnostic type, so it can be used in other IDEs. - // Here we convert VSCode Diagnostic to LSP Diagnostic to make formatDiagnostic recognize it. - let formattedMessage = cache.get(diagnostic.message); - - if (!formattedMessage) { - const markdownString = new MarkdownString( - formatDiagnostic(converter.asDiagnostic(diagnostic)) - ); - - markdownString.isTrusted = true; - markdownString.supportHtml = true; - - formattedMessage = markdownString; - cache.set(diagnostic.message, formattedMessage); - - if (cache.size > CACHE_SIZE_MAX) { - const firstCacheKey = cache.keys().next().value; - cache.delete(firstCacheKey); - } - } - - return { - range: diagnostic.range, - contents: [formattedMessage], - }; - }); + const items: FormattedDiagnostic[] = supportedDiagnostics.map( + (diagnostic) => getFormattedDiagnostic(diagnostic, converter) + ); - uriStore.set(uri.fsPath, items); + // TODO: we should check if never deleting the entries is a performance issue + // probably not, since solving all diagnostics for a file should set its value to an empty collection, but we should check anyway + // see: https://github.com/yoavbls/pretty-ts-errors/issues/139 + formattedDiagnosticsStore.set(uri.fsPath, items); if (items.length > 0) { ensureHoverProviderIsRegistered(uri, context); @@ -76,6 +58,77 @@ export function registerOnDidChangeDiagnostics(context: ExtensionContext) { ); } +/** + * To prevent infinite memory consumtion use a max size for the cache + * + * TODO: consider making this configurable to the end user with a sensible `min` and `max` + */ +const CACHE_SIZE_MAX = 100; + +/** + * Creates a cache with `size` entries pre-filled with empty values. + */ +function createCache(size: number): Map { + const emptyString = ""; + const emptyMarkdownString = new MarkdownString(); + return new Map( + Array.from({ length: size }).map(() => [emptyString, emptyMarkdownString]) + ); +} + +/** + * A local cache that maps TS diagnostics as `string` to their formatted `MarkdownString` counter part. + * @see https://github.com/yoavbls/pretty-ts-errors/pull/62 + * + * One reason this cache is critical is because the TypeScript Language Features extension is very noisy and will constantly push all diagnostics for a file, + * even if there were no actual changes. + * @see https://github.com/yoavbls/pretty-ts-errors/issues/139#issuecomment-3401279357 + * + * TODO: create a proper LRU cache, to prevent exceeding the cache size being a bottleneck + * @see https://github.com/yoavbls/pretty-ts-errors/issues/104 + */ +const cache = createCache(CACHE_SIZE_MAX); + +function getFormattedDiagnostic( + diagnostic: Diagnostic, + converter: Converter +): FormattedDiagnostic { + let formattedMessage = cache.get(diagnostic.message); + + if (!formattedMessage) { + // formatDiagnostic converts message based on LSP Diagnostic type, not VSCode Diagnostic type, so it can be used in other IDEs. + // Here we convert VSCode Diagnostic to LSP Diagnostic to make formatDiagnostic recognize it. + const lspDiagnostic = converter.asDiagnostic(diagnostic); + const formattedDiagnostic = formatDiagnostic(lspDiagnostic); + const markdownString = new MarkdownString(formattedDiagnostic); + + // TODO: consider using the `{ enabledCommands: string[] }` variant, to only allow whitelisted commands + markdownString.isTrusted = true; + markdownString.supportHtml = true; + + formattedMessage = markdownString; + cache.set(diagnostic.message, formattedMessage); + + if (cache.size > CACHE_SIZE_MAX) { + const firstCacheKey = cache.keys().next().value!; + cache.delete(firstCacheKey); + } + } + + return { + range: diagnostic.range, + contents: [formattedMessage], + }; +} + +/** + * A set to prevent registering duplicate hover providers. + */ +const registeredLanguages = new Set(); + +/** + * Ensure a hover provider is registered for any visible editors where pretty-ts-errors has a formatted diagnostic + */ function ensureHoverProviderIsRegistered(uri: Uri, context: ExtensionContext) { const editor = window.visibleTextEditors.find( (editor) => editor.document.uri.toString() === uri.toString() diff --git a/apps/vscode-extension/src/formattedDiagnosticsStore.ts b/apps/vscode-extension/src/formattedDiagnosticsStore.ts new file mode 100644 index 0000000..87b3f67 --- /dev/null +++ b/apps/vscode-extension/src/formattedDiagnosticsStore.ts @@ -0,0 +1,18 @@ +import { MarkdownString, Range, Uri } from "vscode"; + +type CacheKey = Uri["fsPath"]; + +export interface FormattedDiagnostic { + range: Range; + contents: MarkdownString[]; +} + +/** + * A store for formatted diagnostics, where the key is the file path to a file, and the value a collection of formatted diagnostics for that file. + * + * The `onDidChangeDiagnostics` event handler will fill the store with formatted diagnostics, while other components will query the store to display these diagnostics. + */ +export const formattedDiagnosticsStore = new Map< + CacheKey, + FormattedDiagnostic[] +>(); diff --git a/apps/vscode-extension/src/provider/hoverProvider.ts b/apps/vscode-extension/src/provider/hoverProvider.ts index 2882bce..b645140 100644 --- a/apps/vscode-extension/src/provider/hoverProvider.ts +++ b/apps/vscode-extension/src/provider/hoverProvider.ts @@ -1,9 +1,9 @@ import { HoverProvider } from "vscode"; -import { uriStore } from "./uriStore"; +import { formattedDiagnosticsStore } from "../formattedDiagnosticsStore"; export const hoverProvider: HoverProvider = { provideHover(document, position, _token) { - const itemsInUriStore = uriStore.get(document.uri.fsPath); + const itemsInUriStore = formattedDiagnosticsStore.get(document.uri.fsPath); if (!itemsInUriStore) { return null; diff --git a/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts b/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts index a7dc850..e6fb059 100644 --- a/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts +++ b/apps/vscode-extension/src/provider/selectedTextHoverProvider.ts @@ -8,7 +8,7 @@ import { window, } from "vscode"; import { createConverter } from "vscode-languageclient/lib/common/codeConverter"; -import { uriStore } from "./uriStore"; +import { formattedDiagnosticsStore } from "../formattedDiagnosticsStore"; /** * Register an hover provider in debug only. @@ -58,7 +58,9 @@ export function registerSelectedTextHoverProvider(context: ExtensionContext) { markdown.isTrusted = true; markdown.supportHtml = true; - uriStore.set(document.uri.fsPath, [{ range, contents: [markdown] }]); + formattedDiagnosticsStore.set(document.uri.fsPath, [ + { range, contents: [markdown] }, + ]); return { contents: [markdown], diff --git a/apps/vscode-extension/src/provider/textDocumentContentProvider.ts b/apps/vscode-extension/src/provider/textDocumentContentProvider.ts index 0b69dd4..3a66917 100644 --- a/apps/vscode-extension/src/provider/textDocumentContentProvider.ts +++ b/apps/vscode-extension/src/provider/textDocumentContentProvider.ts @@ -4,7 +4,7 @@ import { workspace, type TextDocumentContentProvider, } from "vscode"; -import { uriStore } from "./uriStore"; +import { formattedDiagnosticsStore } from "../formattedDiagnosticsStore"; export const PRETTY_TS_ERRORS_SCHEME = "pretty-ts-errors"; @@ -32,7 +32,7 @@ export const textDocumentContentProvider: TextDocumentContentProvider = { return `only supports .md file extensions for ${uri.fsPath}`; } const fsPath = uri.fsPath.slice(0, -3); - const items = uriStore.get(fsPath); + const items = formattedDiagnosticsStore.get(fsPath); if (!items) { return `no diagnostics found for ${fsPath}`; } diff --git a/apps/vscode-extension/src/provider/uriStore.ts b/apps/vscode-extension/src/provider/uriStore.ts deleted file mode 100644 index 5b1dffa..0000000 --- a/apps/vscode-extension/src/provider/uriStore.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { MarkdownString, Range, Uri } from "vscode"; - -export const uriStore = new Map< - Uri["path"], - { - range: Range; - contents: MarkdownString[]; - }[] ->(); diff --git a/apps/vscode-extension/src/provider/webviewViewProvider.ts b/apps/vscode-extension/src/provider/webviewViewProvider.ts index 28851dc..4e51f32 100644 --- a/apps/vscode-extension/src/provider/webviewViewProvider.ts +++ b/apps/vscode-extension/src/provider/webviewViewProvider.ts @@ -1,7 +1,10 @@ import type { ExtensionContext } from "vscode"; import * as vscode from "vscode"; import { MarkdownWebviewProvider } from "./markdownWebviewProvider"; -import { uriStore } from "./uriStore"; +import { + formattedDiagnosticsStore, + type FormattedDiagnostic, +} from "../formattedDiagnosticsStore"; import { has } from "packages/utils"; const SUPPORTED_LANGUAGE_IDS = [ @@ -23,13 +26,9 @@ export function registerWebviewViewProvider(context: ExtensionContext) { ); } -type CachedDiagnostic = NonNullable< - ReturnType<(typeof uriStore)["get"]> ->[number]; - class MarkdownWebviewViewProvider implements vscode.WebviewViewProvider { private disposables = new Map(); - private shownDiagnostics = new WeakMap(); + private shownDiagnostics = new WeakMap(); constructor(private readonly provider: MarkdownWebviewProvider) {} async resolveWebviewView( @@ -92,7 +91,7 @@ class MarkdownWebviewViewProvider implements vscode.WebviewViewProvider { const selection = activeEditor?.selection; if (activeEditor && selection) { const uri = activeEditor.document.uri; - const diagnostics = uriStore.get(uri.fsPath) ?? []; + const diagnostics = formattedDiagnosticsStore.get(uri.fsPath) ?? []; const diagnostic = diagnostics.find((diagnostic) => diagnostic.range.contains(selection) ); From 174d658de91a7b3e00d5679173a6c627ed01ee15 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Tue, 30 Dec 2025 16:23:22 +0100 Subject: [PATCH 03/14] sort imports --- apps/vscode-extension/src/extension.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/vscode-extension/src/extension.ts b/apps/vscode-extension/src/extension.ts index 010b3ee..9292d3c 100644 --- a/apps/vscode-extension/src/extension.ts +++ b/apps/vscode-extension/src/extension.ts @@ -1,12 +1,12 @@ import { ExtensionContext } from "vscode"; -import { registerSelectedTextHoverProvider } from "./provider/selectedTextHoverProvider"; import { registerOnDidChangeDiagnostics } from "./diagnostics"; import { logger } from "./logger"; -import { registerTextDocumentProvider } from "./provider/textDocumentContentProvider"; +import { registerCopyError } from "./commands/copyError"; +import { registerRevealSelection } from "./commands/revealSelection"; import { registerMarkdownWebviewProvider } from "./provider/markdownWebviewProvider"; +import { registerSelectedTextHoverProvider } from "./provider/selectedTextHoverProvider"; +import { registerTextDocumentProvider } from "./provider/textDocumentContentProvider"; import { registerWebviewViewProvider } from "./provider/webviewViewProvider"; -import { registerRevealSelection } from "./commands/revealSelection"; -import { registerCopyError } from "./commands/copyError"; export function activate(context: ExtensionContext) { // logging and debug features From de09badab17d1b8f9861893dbf721b397a550e29 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Tue, 30 Dec 2025 19:30:21 +0100 Subject: [PATCH 04/14] improve logger; add logging to copyError command --- .../src/commands/copyError.ts | 10 +++- apps/vscode-extension/src/logger.ts | 48 +++++++++++++++---- eslint.config.mjs | 2 +- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/apps/vscode-extension/src/commands/copyError.ts b/apps/vscode-extension/src/commands/copyError.ts index eaaa182..b8c9ede 100644 --- a/apps/vscode-extension/src/commands/copyError.ts +++ b/apps/vscode-extension/src/commands/copyError.ts @@ -1,10 +1,18 @@ import { commands, env, window, type ExtensionContext } from "vscode"; +import { logger } from "../logger"; export function registerCopyError(context: ExtensionContext) { context.subscriptions.push( commands.registerCommand( "prettyTsErrors.copyError", - async (errorMessage: string) => { + async (errorMessage: unknown) => { + if (typeof errorMessage !== "string") { + logger.error( + "cannot write non-string value to clipboard", + errorMessage + ); + return; + } await env.clipboard.writeText(errorMessage); window.showInformationMessage("Copied error message to clipboard!"); } diff --git a/apps/vscode-extension/src/logger.ts b/apps/vscode-extension/src/logger.ts index e70541a..5e906d8 100644 --- a/apps/vscode-extension/src/logger.ts +++ b/apps/vscode-extension/src/logger.ts @@ -32,8 +32,10 @@ function error(...args: Parameters) { } type LogLevel = "info" | "trace" | "debug" | "warn" | "error"; +type LogLevelThresholds = Record; +type SortedLogLevelThresholds = [LogLevel, number][]; -const defaultThresholds: Record = { +const defaultThresholds: LogLevelThresholds = { error: 5000, warn: 1000, info: 100, @@ -56,21 +58,42 @@ declare const performance: import("perf_hooks").Performance; function measure( name: string, task: () => T, - logLevelThresholds: Partial> = {} + logLevelThresholds: Partial = {} ): T { const start = performance.now(); const result = task(); + if (isPromiseLike(result)) { + logger.warn("cannot log.measure async tasks", task, result); + return result; + } const end = performance.now(); const duration = end - start; + const thresholds = normalizeThresholds(logLevelThresholds); + const level = findLogLevel(thresholds, duration); + getLogger()[level](`task ${name} took ${duration.toFixed(3)}ms`); + return result; +} + +function normalizeThresholds( + logLevelThresholds: Partial +): SortedLogLevelThresholds { logLevelThresholds = Object.assign({}, defaultThresholds, logLevelThresholds); - const thresholds = Object.entries(logLevelThresholds) as [LogLevel, number][]; // sort thresholds from high to low // { info: 100, warn: 1000, trace: 0 } => [[warn, 1000], [info, 100], [trace, 0]] - thresholds.sort(([_a, a], [_b, b]) => b - a); - const level: LogLevel = - thresholds.find(([_, threshold]) => duration > threshold)?.[0] || "trace"; - getLogger()[level](`${name} took ${duration.toFixed(3)}ms`); - return result; + return Object.entries(logLevelThresholds).sort( + ([_a, a], [_b, b]) => b - a + ) as SortedLogLevelThresholds; +} + +function findLogLevel( + thresholds: SortedLogLevelThresholds, + duration: number, + defaultLogLevel: LogLevel = "debug" +): LogLevel { + return ( + thresholds.find(([_, threshold]) => duration > threshold)?.[0] ?? + defaultLogLevel + ); } function dispose() { @@ -80,6 +103,15 @@ function dispose() { } } +function isPromiseLike(value: unknown): value is PromiseLike { + return ( + value != null && + typeof value === "object" && + "then" in value && + typeof value["then"] === "function" + ); +} + export const logger = { trace, debug, diff --git a/eslint.config.mjs b/eslint.config.mjs index a05bce5..671c303 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -41,7 +41,7 @@ export default tseslint.config( "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-non-null-assertion": "off", curly: "warn", - eqeqeq: "warn", + eqeqeq: ["warn", { smart: true }], "no-throw-literal": "warn", semi: "off", }, From d8409dd7ba3d7560a83f58fffdfa669150e2f9b7 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Tue, 30 Dec 2025 19:47:08 +0100 Subject: [PATCH 05/14] split revealSelection into functions; add input validation; add logging; --- .../src/commands/revealSelection.ts | 186 +++++++++++++----- 1 file changed, 140 insertions(+), 46 deletions(-) diff --git a/apps/vscode-extension/src/commands/revealSelection.ts b/apps/vscode-extension/src/commands/revealSelection.ts index 7773c07..eb43819 100644 --- a/apps/vscode-extension/src/commands/revealSelection.ts +++ b/apps/vscode-extension/src/commands/revealSelection.ts @@ -1,5 +1,6 @@ import { type ExtensionContext, + type Tab, commands, Range, TabInputText, @@ -9,59 +10,24 @@ import { window, } from "vscode"; import { MarkdownWebviewProvider } from "../provider/markdownWebviewProvider"; +import { logger } from "../logger"; export function registerRevealSelection(context: ExtensionContext) { context.subscriptions.push( commands.registerCommand( "prettyTsErrors.revealSelection", - async (uri: Uri, range: Range) => { - // ensure these are real instances - uri = Uri.from({ ...uri }); - range = new Range( - range.start.line, - range.start.character, - range.end.line, - range.end.character - ); - - // default behaviour is to use the active view column - let viewColumn = ViewColumn.Active; - - // detect if the active tab is our preview webview - let isFromMarkdownPreviewWebview = false; - const activeTab = window.tabGroups.activeTabGroup.activeTab; - if (activeTab && activeTab.input instanceof TabInputWebview) { - // For an unknown reason this string is prefixed with something like `mainthread-${viewType}` - // endsWith should handle a full match and the prefixed versions - if ( - activeTab.input.viewType.endsWith(MarkdownWebviewProvider.viewType) - ) { - isFromMarkdownPreviewWebview = true; - } - } - - if (isFromMarkdownPreviewWebview) { - // find a tab group where the file is open, then use that view column for the `vscode.open` command - const tabs = window.tabGroups.all.flatMap( - (tabGroup) => tabGroup.tabs + async (maybeUriLike: unknown, maybeRangeLike: unknown) => { + const { isValidUri, uri } = tryEnsureUri(maybeUriLike); + const { isValidRange, range } = tryEnsureRange(maybeRangeLike); + if (!isValidUri || !isValidRange) { + logger.error( + "cannot reveal selection with invalid range or uri", + maybeRangeLike, + maybeUriLike ); - const tabWithFileOpen = tabs.find((tab) => { - if (tab.input instanceof TabInputText) { - return tab.input.uri.toString() === uri.toString(); - } - return false; - }); - if (tabWithFileOpen) { - viewColumn = tabWithFileOpen.group.viewColumn; - } else { - // If markdown preview is not open on 1, open the link in 1, else open the link in 2 - viewColumn = - activeTab!.group.viewColumn !== 1 - ? ViewColumn.One - : ViewColumn.Two; - } + return; } - + const viewColumn = determineViewColumn(uri); return commands.executeCommand("vscode.open", uri, { selection: range, viewColumn, @@ -70,3 +36,131 @@ export function registerRevealSelection(context: ExtensionContext) { ) ); } + +/** + * Determine the view column to use for the `vscode.open` command: + * - if the command is not called from a markdown webview preview, default to `ViewColumn.Active`, which will defer the decision to VS Code + * - else check if the file is open somewhere and use its view column + * - else use the opposite of where the preview resides (left if the preview is right, right if the preview is left) + * + * This seems a bit complex, but without it VS Code will open a new view column to the right and open the given uri in it, regardless of the current layout and open files. + * Using this algorithm makes it feel more intuitive and less stupid. + */ +function determineViewColumn(uri: Uri): ViewColumn { + if (!isFromMarkdownPreviewWebview()) { + return ViewColumn.Active; + } + const tab = findTabWithFileOpen(uri); + if (tab) { + return tab.group.viewColumn; + } + // If markdown preview is not open on 1, open the link in 1, else open the link in 2 + const activeTab = window.tabGroups.activeTabGroup.activeTab; + return activeTab!.group.viewColumn !== 1 ? ViewColumn.One : ViewColumn.Two; +} + +/** + * Search for an open tab with the given `uri` and return it if it exists + */ +function findTabWithFileOpen(uri: Uri): Tab | undefined { + const tabs = window.tabGroups.all.flatMap((tabGroup) => tabGroup.tabs); + return tabs.find((tab) => { + if (tab.input instanceof TabInputText) { + return tab.input.uri.toString() === uri.toString(); + } + return false; + }); +} + +/** + * Returns `true` if the active tab is a pretty-ts-errors markdown preview webview + */ +function isFromMarkdownPreviewWebview(): boolean { + const activeTab = window.tabGroups.activeTabGroup.activeTab; + if (activeTab && activeTab.input instanceof TabInputWebview) { + // For an unknown reason this string is prefixed with something like `mainthread-${viewType}` + // endsWith should handle a full match and the prefixed versions + if (activeTab.input.viewType.endsWith(MarkdownWebviewProvider.viewType)) { + return true; + } + } + return false; +} + +function tryEnsureUri( + maybeUriLike: unknown +): { isValidUri: true; uri: Uri } | { isValidUri: false; uri?: undefined } { + if (maybeUriLike instanceof Uri) { + return { isValidUri: true, uri: maybeUriLike }; + } + if (typeof maybeUriLike === "string") { + try { + return { isValidUri: true, uri: Uri.parse(maybeUriLike) }; + } catch (error) { + return { isValidUri: false }; + } + } + if (isUriLike(maybeUriLike)) { + return { isValidUri: true, uri: Uri.from(maybeUriLike) }; + } + return { isValidUri: false }; +} + +type UriLike = Parameters[0]; + +function isUriLike(value: unknown): value is UriLike { + return ( + typeof value === "object" && + value != null && + "scheme" in value && + typeof value.scheme === "string" + ); +} + +function tryEnsureRange( + maybeRangeLike: unknown +): + | { isValidRange: true; range: Range } + | { isValidRange: false; range?: undefined } { + if (maybeRangeLike instanceof Range) { + return { isValidRange: true, range: maybeRangeLike }; + } + if (isRangeLike(maybeRangeLike)) { + return { + isValidRange: true, + range: new Range( + maybeRangeLike.start.line, + maybeRangeLike.start.character, + maybeRangeLike.end.line, + maybeRangeLike.end.character + ), + }; + } + return { isValidRange: false }; +} + +type RangeLike = { start: PositionLike; end: PositionLike }; + +function isRangeLike(value: unknown): value is RangeLike { + return ( + typeof value === "object" && + value != null && + "start" in value && + isPositionLike(value.start) && + "end" in value && + isPositionLike(value.end) + ); +} + +type PositionLike = { line: number; character: number }; + +function isPositionLike(value: unknown): value is PositionLike { + return ( + typeof value === "object" && + value !== null && + "line" in value && + typeof value.line === "number" && + "character" in value && + typeof value.character === "number" + ); +} From b69eabb52575255d8ec76dd401a1ebf72d8cf6f4 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Tue, 30 Dec 2025 20:06:33 +0100 Subject: [PATCH 06/14] refactor the openMarkdownPreview as a seperate command; increase security of markdown preview provider; add logging on invalid input; --- .../src/commands/openMarkdownPreview.ts | 25 ++++++ .../src/commands/revealSelection.ts | 80 +------------------ .../vscode-extension/src/commands/validate.ts | 79 ++++++++++++++++++ apps/vscode-extension/src/extension.ts | 6 +- .../src/provider/hoverProvider.ts | 8 +- .../src/provider/markdownWebviewProvider.ts | 29 +++---- 6 files changed, 120 insertions(+), 107 deletions(-) create mode 100644 apps/vscode-extension/src/commands/openMarkdownPreview.ts create mode 100644 apps/vscode-extension/src/commands/validate.ts diff --git a/apps/vscode-extension/src/commands/openMarkdownPreview.ts b/apps/vscode-extension/src/commands/openMarkdownPreview.ts new file mode 100644 index 0000000..333fb48 --- /dev/null +++ b/apps/vscode-extension/src/commands/openMarkdownPreview.ts @@ -0,0 +1,25 @@ +import type { ExtensionContext } from "vscode"; +import { commands } from "vscode"; +import { MarkdownWebviewProvider } from "../provider/markdownWebviewProvider"; +import { tryEnsureUri } from "./validate"; +import { logger } from "../logger"; + +export function registerOpenMarkdownPreview(context: ExtensionContext) { + const provider = new MarkdownWebviewProvider(context); + context.subscriptions.push( + commands.registerCommand( + "prettyTsErrors.openMarkdownPreview", + async (maybeUriLike: unknown) => { + const { isValidUri, uri } = tryEnsureUri(maybeUriLike); + if (!isValidUri) { + logger.error( + "cannot open markdown preview with an invalid uri", + maybeUriLike + ); + return; + } + await provider.openMarkdownPreview(uri); + } + ) + ); +} diff --git a/apps/vscode-extension/src/commands/revealSelection.ts b/apps/vscode-extension/src/commands/revealSelection.ts index eb43819..be1d5cb 100644 --- a/apps/vscode-extension/src/commands/revealSelection.ts +++ b/apps/vscode-extension/src/commands/revealSelection.ts @@ -2,7 +2,6 @@ import { type ExtensionContext, type Tab, commands, - Range, TabInputText, TabInputWebview, Uri, @@ -11,6 +10,7 @@ import { } from "vscode"; import { MarkdownWebviewProvider } from "../provider/markdownWebviewProvider"; import { logger } from "../logger"; +import { tryEnsureRange, tryEnsureUri } from "./validate"; export function registerRevealSelection(context: ExtensionContext) { context.subscriptions.push( @@ -86,81 +86,3 @@ function isFromMarkdownPreviewWebview(): boolean { } return false; } - -function tryEnsureUri( - maybeUriLike: unknown -): { isValidUri: true; uri: Uri } | { isValidUri: false; uri?: undefined } { - if (maybeUriLike instanceof Uri) { - return { isValidUri: true, uri: maybeUriLike }; - } - if (typeof maybeUriLike === "string") { - try { - return { isValidUri: true, uri: Uri.parse(maybeUriLike) }; - } catch (error) { - return { isValidUri: false }; - } - } - if (isUriLike(maybeUriLike)) { - return { isValidUri: true, uri: Uri.from(maybeUriLike) }; - } - return { isValidUri: false }; -} - -type UriLike = Parameters[0]; - -function isUriLike(value: unknown): value is UriLike { - return ( - typeof value === "object" && - value != null && - "scheme" in value && - typeof value.scheme === "string" - ); -} - -function tryEnsureRange( - maybeRangeLike: unknown -): - | { isValidRange: true; range: Range } - | { isValidRange: false; range?: undefined } { - if (maybeRangeLike instanceof Range) { - return { isValidRange: true, range: maybeRangeLike }; - } - if (isRangeLike(maybeRangeLike)) { - return { - isValidRange: true, - range: new Range( - maybeRangeLike.start.line, - maybeRangeLike.start.character, - maybeRangeLike.end.line, - maybeRangeLike.end.character - ), - }; - } - return { isValidRange: false }; -} - -type RangeLike = { start: PositionLike; end: PositionLike }; - -function isRangeLike(value: unknown): value is RangeLike { - return ( - typeof value === "object" && - value != null && - "start" in value && - isPositionLike(value.start) && - "end" in value && - isPositionLike(value.end) - ); -} - -type PositionLike = { line: number; character: number }; - -function isPositionLike(value: unknown): value is PositionLike { - return ( - typeof value === "object" && - value !== null && - "line" in value && - typeof value.line === "number" && - "character" in value && - typeof value.character === "number" - ); -} diff --git a/apps/vscode-extension/src/commands/validate.ts b/apps/vscode-extension/src/commands/validate.ts new file mode 100644 index 0000000..38d47a5 --- /dev/null +++ b/apps/vscode-extension/src/commands/validate.ts @@ -0,0 +1,79 @@ +import { Range, Uri } from "vscode"; + +export function tryEnsureUri( + maybeUriLike: unknown +): { isValidUri: true; uri: Uri } | { isValidUri: false; uri?: undefined } { + if (maybeUriLike instanceof Uri) { + return { isValidUri: true, uri: maybeUriLike }; + } + if (typeof maybeUriLike === "string") { + try { + return { isValidUri: true, uri: Uri.parse(maybeUriLike) }; + } catch (error) { + return { isValidUri: false }; + } + } + if (isUriLike(maybeUriLike)) { + return { isValidUri: true, uri: Uri.from(maybeUriLike) }; + } + return { isValidUri: false }; +} + +type UriLike = Parameters[0]; + +function isUriLike(value: unknown): value is UriLike { + return ( + typeof value === "object" && + value != null && + "scheme" in value && + typeof value.scheme === "string" + ); +} + +export function tryEnsureRange( + maybeRangeLike: unknown +): + | { isValidRange: true; range: Range } + | { isValidRange: false; range?: undefined } { + if (maybeRangeLike instanceof Range) { + return { isValidRange: true, range: maybeRangeLike }; + } + if (isRangeLike(maybeRangeLike)) { + return { + isValidRange: true, + range: new Range( + maybeRangeLike.start.line, + maybeRangeLike.start.character, + maybeRangeLike.end.line, + maybeRangeLike.end.character + ), + }; + } + return { isValidRange: false }; +} + +type RangeLike = { start: PositionLike; end: PositionLike }; + +function isRangeLike(value: unknown): value is RangeLike { + return ( + typeof value === "object" && + value != null && + "start" in value && + isPositionLike(value.start) && + "end" in value && + isPositionLike(value.end) + ); +} + +type PositionLike = { line: number; character: number }; + +function isPositionLike(value: unknown): value is PositionLike { + return ( + typeof value === "object" && + value !== null && + "line" in value && + typeof value.line === "number" && + "character" in value && + typeof value.character === "number" + ); +} diff --git a/apps/vscode-extension/src/extension.ts b/apps/vscode-extension/src/extension.ts index 9292d3c..51d32b3 100644 --- a/apps/vscode-extension/src/extension.ts +++ b/apps/vscode-extension/src/extension.ts @@ -3,7 +3,7 @@ import { registerOnDidChangeDiagnostics } from "./diagnostics"; import { logger } from "./logger"; import { registerCopyError } from "./commands/copyError"; import { registerRevealSelection } from "./commands/revealSelection"; -import { registerMarkdownWebviewProvider } from "./provider/markdownWebviewProvider"; +import { registerOpenMarkdownPreview } from "./commands/openMarkdownPreview"; import { registerSelectedTextHoverProvider } from "./provider/selectedTextHoverProvider"; import { registerTextDocumentProvider } from "./provider/textDocumentContentProvider"; import { registerWebviewViewProvider } from "./provider/webviewViewProvider"; @@ -19,12 +19,12 @@ export function activate(context: ExtensionContext) { // UI elements that show the prettified diagnostics registerTextDocumentProvider(context); - registerMarkdownWebviewProvider(context); registerWebviewViewProvider(context); // register commands - registerRevealSelection(context); registerCopyError(context); + registerOpenMarkdownPreview(context); + registerRevealSelection(context); } export function deactivate() { diff --git a/apps/vscode-extension/src/provider/hoverProvider.ts b/apps/vscode-extension/src/provider/hoverProvider.ts index b645140..ffb19d6 100644 --- a/apps/vscode-extension/src/provider/hoverProvider.ts +++ b/apps/vscode-extension/src/provider/hoverProvider.ts @@ -3,15 +3,13 @@ import { formattedDiagnosticsStore } from "../formattedDiagnosticsStore"; export const hoverProvider: HoverProvider = { provideHover(document, position, _token) { - const itemsInUriStore = formattedDiagnosticsStore.get(document.uri.fsPath); + const items = formattedDiagnosticsStore.get(document.uri.fsPath); - if (!itemsInUriStore) { + if (!items) { return null; } - const itemInRange = itemsInUriStore.filter((item) => - item.range.contains(position) - ); + const itemInRange = items.filter((item) => item.range.contains(position)); if (itemInRange.length === 0) { return null; diff --git a/apps/vscode-extension/src/provider/markdownWebviewProvider.ts b/apps/vscode-extension/src/provider/markdownWebviewProvider.ts index 1c2476a..2e795b2 100644 --- a/apps/vscode-extension/src/provider/markdownWebviewProvider.ts +++ b/apps/vscode-extension/src/provider/markdownWebviewProvider.ts @@ -1,33 +1,16 @@ -import type { ExtensionContext } from "vscode"; import * as vscode from "vscode"; import { getUserLangs, getUserTheme } from "vscode-shiki-bridge"; import { HighlighterCore, createHighlighterCore } from "shiki/core"; import { createOnigurumaEngine } from "shiki/engine/oniguruma"; import { createMarkdownExit, type MarkdownExit } from "markdown-exit"; - -export function registerMarkdownWebviewProvider(context: ExtensionContext) { - const provider = new MarkdownWebviewProvider(context); - context.subscriptions.push( - vscode.commands.registerCommand( - "prettyTsErrors.openMarkdownPreview", - async (uri: vscode.Uri) => { - if (!uri || !(uri instanceof vscode.Uri)) { - console.error( - "expected uri to be an instance of vscode.Uri, instead got: ", - uri - ); - return; - } - await provider.openMarkdownPreview(uri); - } - ) - ); -} +import { PRETTY_TS_ERRORS_SCHEME } from "./textDocumentContentProvider"; function createMarkdownExitPatched( highlight: (code: string) => Promise ) { const md = createMarkdownExit({ + // TODO: try and refactor this to not use a markdown renderer, this would remove this possible XSS attack vector + // @see https://github.com/yoavbls/pretty-ts-errors/pull/152#issuecomment-3690510196 html: true, highlight, }); @@ -120,6 +103,12 @@ export class MarkdownWebviewProvider { } async openMarkdownPreview(uri: vscode.Uri) { + // until the markdown renderer has been removed, try and avoid rendering unknown uri's to limit the chance of someone finding an XSS vulnerability. + if (uri.scheme !== PRETTY_TS_ERRORS_SCHEME) { + throw new Error( + `cannot provide a markdown preview for a non '${PRETTY_TS_ERRORS_SCHEME}' scheme uri` + ); + } const document = await vscode.workspace.openTextDocument(uri); const markdown = document.getText(); const content = await this.renderMarkdown(markdown); From 354982fcfdeb316622125d23a918c8dd04700538 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Tue, 30 Dec 2025 20:26:40 +0100 Subject: [PATCH 07/14] add generic logging to commands --- .../src/commands/copyError.ts | 19 ++++---- apps/vscode-extension/src/commands/execute.ts | 24 ++++++++++ .../src/commands/openMarkdownPreview.ts | 19 ++++---- .../src/commands/revealSelection.ts | 44 +++++++++++-------- 4 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 apps/vscode-extension/src/commands/execute.ts diff --git a/apps/vscode-extension/src/commands/copyError.ts b/apps/vscode-extension/src/commands/copyError.ts index b8c9ede..e44aa3a 100644 --- a/apps/vscode-extension/src/commands/copyError.ts +++ b/apps/vscode-extension/src/commands/copyError.ts @@ -1,21 +1,20 @@ import { commands, env, window, type ExtensionContext } from "vscode"; -import { logger } from "../logger"; +import { execute } from "./execute"; + +const COMMAND_ID = "prettyTsErrors.copyError"; export function registerCopyError(context: ExtensionContext) { context.subscriptions.push( - commands.registerCommand( - "prettyTsErrors.copyError", - async (errorMessage: unknown) => { + commands.registerCommand(COMMAND_ID, async (errorMessage: unknown) => + execute(COMMAND_ID, async () => { if (typeof errorMessage !== "string") { - logger.error( - "cannot write non-string value to clipboard", - errorMessage - ); - return; + throw new Error("cannot write non-string value to clipboard", { + cause: errorMessage, + }); } await env.clipboard.writeText(errorMessage); window.showInformationMessage("Copied error message to clipboard!"); - } + }) ) ); } diff --git a/apps/vscode-extension/src/commands/execute.ts b/apps/vscode-extension/src/commands/execute.ts new file mode 100644 index 0000000..01ded82 --- /dev/null +++ b/apps/vscode-extension/src/commands/execute.ts @@ -0,0 +1,24 @@ +import { window } from "vscode"; +import { logger } from "../logger"; + +/** + * A wrapper function to execute command tasks while providing user feedback and logging on errors. + */ +export async function execute( + commandName: string, + task: (...args: unknown[]) => unknown | Promise +) { + try { + return await task(); + } catch (error) { + if (error instanceof Error) { + logger.error(error); + } else if (typeof error === "string") { + logger.error(error); + } else { + logger.error("caught non-string or error value: ", error); + } + window.showErrorMessage(`Failed to execute command: '${commandName}'`); + throw error; + } +} diff --git a/apps/vscode-extension/src/commands/openMarkdownPreview.ts b/apps/vscode-extension/src/commands/openMarkdownPreview.ts index 333fb48..c567deb 100644 --- a/apps/vscode-extension/src/commands/openMarkdownPreview.ts +++ b/apps/vscode-extension/src/commands/openMarkdownPreview.ts @@ -2,24 +2,23 @@ import type { ExtensionContext } from "vscode"; import { commands } from "vscode"; import { MarkdownWebviewProvider } from "../provider/markdownWebviewProvider"; import { tryEnsureUri } from "./validate"; -import { logger } from "../logger"; +import { execute } from "./execute"; + +const COMMAND_ID = "prettyTsErrors.openMarkdownPreview"; export function registerOpenMarkdownPreview(context: ExtensionContext) { const provider = new MarkdownWebviewProvider(context); context.subscriptions.push( - commands.registerCommand( - "prettyTsErrors.openMarkdownPreview", - async (maybeUriLike: unknown) => { + commands.registerCommand(COMMAND_ID, async (maybeUriLike: unknown) => + execute(COMMAND_ID, async () => { const { isValidUri, uri } = tryEnsureUri(maybeUriLike); if (!isValidUri) { - logger.error( - "cannot open markdown preview with an invalid uri", - maybeUriLike - ); - return; + throw new Error("cannot open markdown preview with an invalid uri", { + cause: maybeUriLike, + }); } await provider.openMarkdownPreview(uri); - } + }) ) ); } diff --git a/apps/vscode-extension/src/commands/revealSelection.ts b/apps/vscode-extension/src/commands/revealSelection.ts index be1d5cb..e6ebb8b 100644 --- a/apps/vscode-extension/src/commands/revealSelection.ts +++ b/apps/vscode-extension/src/commands/revealSelection.ts @@ -9,30 +9,36 @@ import { window, } from "vscode"; import { MarkdownWebviewProvider } from "../provider/markdownWebviewProvider"; -import { logger } from "../logger"; import { tryEnsureRange, tryEnsureUri } from "./validate"; +import { execute } from "./execute"; + +const COMMAND_ID = "prettyTsErrors.revealSelection"; export function registerRevealSelection(context: ExtensionContext) { context.subscriptions.push( commands.registerCommand( - "prettyTsErrors.revealSelection", - async (maybeUriLike: unknown, maybeRangeLike: unknown) => { - const { isValidUri, uri } = tryEnsureUri(maybeUriLike); - const { isValidRange, range } = tryEnsureRange(maybeRangeLike); - if (!isValidUri || !isValidRange) { - logger.error( - "cannot reveal selection with invalid range or uri", - maybeRangeLike, - maybeUriLike - ); - return; - } - const viewColumn = determineViewColumn(uri); - return commands.executeCommand("vscode.open", uri, { - selection: range, - viewColumn, - }); - } + COMMAND_ID, + async (maybeUriLike: unknown, maybeRangeLike: unknown) => + execute(COMMAND_ID, async () => { + const { isValidUri, uri } = tryEnsureUri(maybeUriLike); + const { isValidRange, range } = tryEnsureRange(maybeRangeLike); + if (!isValidUri || !isValidRange) { + throw new Error( + "cannot reveal selection with invalid range or uri", + { + cause: { + range: maybeRangeLike, + uri: maybeUriLike, + }, + } + ); + } + const viewColumn = determineViewColumn(uri); + return commands.executeCommand("vscode.open", uri, { + selection: range, + viewColumn, + }); + }) ) ); } From 82a6c57123132a60b1a2f1afd8659b2c90fbf34d Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Tue, 30 Dec 2025 20:40:08 +0100 Subject: [PATCH 08/14] add comments --- apps/vscode-extension/src/provider/webviewViewProvider.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/vscode-extension/src/provider/webviewViewProvider.ts b/apps/vscode-extension/src/provider/webviewViewProvider.ts index 4e51f32..8f75822 100644 --- a/apps/vscode-extension/src/provider/webviewViewProvider.ts +++ b/apps/vscode-extension/src/provider/webviewViewProvider.ts @@ -26,6 +26,7 @@ export function registerWebviewViewProvider(context: ExtensionContext) { ); } +// TODO: adding a `MarkdownWebviewView` class would make this provider a lot simpler class MarkdownWebviewViewProvider implements vscode.WebviewViewProvider { private disposables = new Map(); private shownDiagnostics = new WeakMap(); @@ -49,6 +50,7 @@ class MarkdownWebviewViewProvider implements vscode.WebviewViewProvider { this.provider.createOnDidReceiveMessage() ), vscode.languages.onDidChangeDiagnostics(() => + // TODO: since `onDidChangeDiagnostics` fires often, we should try and avoid calling refresh based on the event uris this.refresh(webviewView.webview) ), vscode.window.onDidChangeActiveTextEditor((editor) => { From d1986bc3266c38ab2e393d79be4d772322fabe5f Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Wed, 31 Dec 2025 15:52:59 +0100 Subject: [PATCH 09/14] add strict to uri parsing --- apps/vscode-extension/src/commands/validate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/vscode-extension/src/commands/validate.ts b/apps/vscode-extension/src/commands/validate.ts index 38d47a5..df8c468 100644 --- a/apps/vscode-extension/src/commands/validate.ts +++ b/apps/vscode-extension/src/commands/validate.ts @@ -8,7 +8,7 @@ export function tryEnsureUri( } if (typeof maybeUriLike === "string") { try { - return { isValidUri: true, uri: Uri.parse(maybeUriLike) }; + return { isValidUri: true, uri: Uri.parse(maybeUriLike, true) }; } catch (error) { return { isValidUri: false }; } From 4258833e5a86a14862bee7986b69f244080539e9 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Wed, 31 Dec 2025 15:54:35 +0100 Subject: [PATCH 10/14] add logging to critical paths; add some dev ux to log output; --- apps/vscode-extension/src/diagnostics.ts | 75 +++++++++---------- apps/vscode-extension/src/extension.ts | 1 + apps/vscode-extension/src/logger.ts | 21 +++++- .../provider/textDocumentContentProvider.ts | 17 ++++- .../src/provider/webviewViewProvider.ts | 2 +- 5 files changed, 72 insertions(+), 44 deletions(-) diff --git a/apps/vscode-extension/src/diagnostics.ts b/apps/vscode-extension/src/diagnostics.ts index 4e64c70..fc270e7 100644 --- a/apps/vscode-extension/src/diagnostics.ts +++ b/apps/vscode-extension/src/diagnostics.ts @@ -17,6 +17,7 @@ import { formattedDiagnosticsStore, type FormattedDiagnostic, } from "./formattedDiagnosticsStore"; +import { logger } from "./logger"; /** * The list of diagnostic sources that pretty-ts-errors supports @@ -33,26 +34,30 @@ export function registerOnDidChangeDiagnostics(context: ExtensionContext) { const converter = createConverter(); context.subscriptions.push( languages.onDidChangeDiagnostics(async (e) => { - e.uris.forEach((uri) => { - const diagnostics = languages.getDiagnostics(uri); - const supportedDiagnostics = diagnostics.filter( - (diagnostic) => - diagnostic.source && - has(supportedDiagnosticSources, diagnostic.source) - ); - - const items: FormattedDiagnostic[] = supportedDiagnostics.map( - (diagnostic) => getFormattedDiagnostic(diagnostic, converter) - ); - - // TODO: we should check if never deleting the entries is a performance issue - // probably not, since solving all diagnostics for a file should set its value to an empty collection, but we should check anyway - // see: https://github.com/yoavbls/pretty-ts-errors/issues/139 - formattedDiagnosticsStore.set(uri.fsPath, items); - - if (items.length > 0) { - ensureHoverProviderIsRegistered(uri, context); - } + logger.measure("onDidChangeDiagnostics", () => { + e.uris.forEach((uri) => { + logger.measure(`diagnostics for: ${uri.toString(true)}`, () => { + const diagnostics = languages.getDiagnostics(uri); + const supportedDiagnostics = diagnostics.filter( + (diagnostic) => + diagnostic.source && + has(supportedDiagnosticSources, diagnostic.source) + ); + + const items: FormattedDiagnostic[] = supportedDiagnostics.map( + (diagnostic) => getFormattedDiagnostic(diagnostic, uri, converter) + ); + + // TODO: we should check if never deleting the entries is a performance issue + // probably not, since solving all diagnostics for a file should set its value to an empty collection, but we should check anyway + // see: https://github.com/yoavbls/pretty-ts-errors/issues/139 + formattedDiagnosticsStore.set(uri.fsPath, items); + + if (items.length > 0) { + ensureHoverProviderIsRegistered(uri, context); + } + }); + }); }); }) ); @@ -65,17 +70,6 @@ export function registerOnDidChangeDiagnostics(context: ExtensionContext) { */ const CACHE_SIZE_MAX = 100; -/** - * Creates a cache with `size` entries pre-filled with empty values. - */ -function createCache(size: number): Map { - const emptyString = ""; - const emptyMarkdownString = new MarkdownString(); - return new Map( - Array.from({ length: size }).map(() => [emptyString, emptyMarkdownString]) - ); -} - /** * A local cache that maps TS diagnostics as `string` to their formatted `MarkdownString` counter part. * @see https://github.com/yoavbls/pretty-ts-errors/pull/62 @@ -87,10 +81,11 @@ function createCache(size: number): Map { * TODO: create a proper LRU cache, to prevent exceeding the cache size being a bottleneck * @see https://github.com/yoavbls/pretty-ts-errors/issues/104 */ -const cache = createCache(CACHE_SIZE_MAX); +const cache = new Map(); function getFormattedDiagnostic( diagnostic: Diagnostic, + uri: Uri, converter: Converter ): FormattedDiagnostic { let formattedMessage = cache.get(diagnostic.message); @@ -99,7 +94,10 @@ function getFormattedDiagnostic( // formatDiagnostic converts message based on LSP Diagnostic type, not VSCode Diagnostic type, so it can be used in other IDEs. // Here we convert VSCode Diagnostic to LSP Diagnostic to make formatDiagnostic recognize it. const lspDiagnostic = converter.asDiagnostic(diagnostic); - const formattedDiagnostic = formatDiagnostic(lspDiagnostic); + const formattedDiagnostic = logger.measure( + `formatDiagnostic(\`${lspDiagnostic.message}\`)`, + () => formatDiagnostic(lspDiagnostic, { uri }) + ); const markdownString = new MarkdownString(formattedDiagnostic); // TODO: consider using the `{ enabledCommands: string[] }` variant, to only allow whitelisted commands @@ -107,12 +105,11 @@ function getFormattedDiagnostic( markdownString.supportHtml = true; formattedMessage = markdownString; - cache.set(diagnostic.message, formattedMessage); - if (cache.size > CACHE_SIZE_MAX) { const firstCacheKey = cache.keys().next().value!; cache.delete(firstCacheKey); } + cache.set(diagnostic.message, formattedMessage); } return { @@ -133,12 +130,14 @@ function ensureHoverProviderIsRegistered(uri: Uri, context: ExtensionContext) { const editor = window.visibleTextEditors.find( (editor) => editor.document.uri.toString() === uri.toString() ); - if (editor && !registeredLanguages.has(editor.document.languageId)) { - registeredLanguages.add(editor.document.languageId); + const languageId = editor?.document.languageId; + if (languageId && !registeredLanguages.has(languageId)) { + logger.debug(`registering hover provider for language id: ${languageId}`); + registeredLanguages.add(languageId); context.subscriptions.push( languages.registerHoverProvider( { - language: editor.document.languageId, + language: languageId, }, hoverProvider ) diff --git a/apps/vscode-extension/src/extension.ts b/apps/vscode-extension/src/extension.ts index 51d32b3..25f4928 100644 --- a/apps/vscode-extension/src/extension.ts +++ b/apps/vscode-extension/src/extension.ts @@ -11,6 +11,7 @@ import { registerWebviewViewProvider } from "./provider/webviewViewProvider"; export function activate(context: ExtensionContext) { // logging and debug features logger.info("activating"); + logger.register(context); context.subscriptions.push(logger); registerSelectedTextHoverProvider(context); diff --git a/apps/vscode-extension/src/logger.ts b/apps/vscode-extension/src/logger.ts index 5e906d8..cf6251c 100644 --- a/apps/vscode-extension/src/logger.ts +++ b/apps/vscode-extension/src/logger.ts @@ -1,4 +1,10 @@ -import { LogOutputChannel, window } from "vscode"; +import { + ExtensionMode, + LogOutputChannel, + window, + type ExtensionContext, + LogLevel as VSLogLevel, +} from "vscode"; let instance: null | LogOutputChannel = null; @@ -112,6 +118,18 @@ function isPromiseLike(value: unknown): value is PromiseLike { ); } +function register(context: ExtensionContext) { + if (context.extensionMode === ExtensionMode.Development) { + const instance = getLogger(); + instance.show(); + if (instance.logLevel !== VSLogLevel.Trace) { + instance.appendLine( + `To see more verbose logging, set this output's log level to "Trace" (gear icon next to the dropdown).` + ); + } + } +} + export const logger = { trace, debug, @@ -119,5 +137,6 @@ export const logger = { warn, error, measure, + register, dispose, }; diff --git a/apps/vscode-extension/src/provider/textDocumentContentProvider.ts b/apps/vscode-extension/src/provider/textDocumentContentProvider.ts index 3a66917..74baac1 100644 --- a/apps/vscode-extension/src/provider/textDocumentContentProvider.ts +++ b/apps/vscode-extension/src/provider/textDocumentContentProvider.ts @@ -5,6 +5,7 @@ import { type TextDocumentContentProvider, } from "vscode"; import { formattedDiagnosticsStore } from "../formattedDiagnosticsStore"; +import { logger } from "../logger"; export const PRETTY_TS_ERRORS_SCHEME = "pretty-ts-errors"; @@ -29,14 +30,19 @@ export const textDocumentContentProvider: TextDocumentContentProvider = { provideTextDocumentContent(uri): string { const searchParams = new URLSearchParams(uri.query); if (!uri.fsPath.endsWith(".md")) { - return `only supports .md file extensions for ${uri.fsPath}`; + logger.error( + `Tried to provide a text document for fsPath: '${uri.fsPath}'` + ); + return `only supports .md file extensions (given ${uri.fsPath})`; } const fsPath = uri.fsPath.slice(0, -3); const items = formattedDiagnosticsStore.get(fsPath); if (!items) { + logger.error(`No diagnostics found for '${fsPath}'`); return `no diagnostics found for ${fsPath}`; } if (!searchParams.has("range")) { + logger.error(`Missing range query parameter for '${uri}'`); return `range query parameter is missing for uri: ${uri}`; } const range = createRangeFromString(searchParams.get("range")!); @@ -44,9 +50,12 @@ export const textDocumentContentProvider: TextDocumentContentProvider = { return item.range.isEqual(range); }); if (!item) { - return `no diagnostic found for ${fsPath} with range ${JSON.stringify( - range - )}`; + const rangeAsString = JSON.stringify(range); + logger.error( + `No diagnostic found for '${fsPath}' and range '${rangeAsString}', items:`, + items + ); + return `no diagnostic found for ${fsPath} with range ${rangeAsString}`; } return item.contents.map((content) => content.value).join("\n"); }, diff --git a/apps/vscode-extension/src/provider/webviewViewProvider.ts b/apps/vscode-extension/src/provider/webviewViewProvider.ts index 8f75822..24db77e 100644 --- a/apps/vscode-extension/src/provider/webviewViewProvider.ts +++ b/apps/vscode-extension/src/provider/webviewViewProvider.ts @@ -5,7 +5,7 @@ import { formattedDiagnosticsStore, type FormattedDiagnostic, } from "../formattedDiagnosticsStore"; -import { has } from "packages/utils"; +import { has } from "@pretty-ts-errors/utils"; const SUPPORTED_LANGUAGE_IDS = [ "typescript", From b6c7d8f8c99b44da40d9ca8b393ce091873d8b24 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Sat, 3 Jan 2026 18:57:42 +0100 Subject: [PATCH 11/14] fix naming --- apps/vscode-extension/src/formattedDiagnosticsStore.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/vscode-extension/src/formattedDiagnosticsStore.ts b/apps/vscode-extension/src/formattedDiagnosticsStore.ts index 87b3f67..9e6b078 100644 --- a/apps/vscode-extension/src/formattedDiagnosticsStore.ts +++ b/apps/vscode-extension/src/formattedDiagnosticsStore.ts @@ -1,6 +1,6 @@ import { MarkdownString, Range, Uri } from "vscode"; -type CacheKey = Uri["fsPath"]; +type StoreKey = Uri["fsPath"]; export interface FormattedDiagnostic { range: Range; @@ -13,6 +13,6 @@ export interface FormattedDiagnostic { * The `onDidChangeDiagnostics` event handler will fill the store with formatted diagnostics, while other components will query the store to display these diagnostics. */ export const formattedDiagnosticsStore = new Map< - CacheKey, + StoreKey, FormattedDiagnostic[] >(); From a118281f51c5c64c16e7fc26eb8eddb8a0d86323 Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Sat, 3 Jan 2026 19:00:53 +0100 Subject: [PATCH 12/14] move logging disposable registering to register fn --- apps/vscode-extension/src/extension.ts | 4 ++-- apps/vscode-extension/src/logger.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/vscode-extension/src/extension.ts b/apps/vscode-extension/src/extension.ts index 25f4928..7345532 100644 --- a/apps/vscode-extension/src/extension.ts +++ b/apps/vscode-extension/src/extension.ts @@ -9,10 +9,10 @@ import { registerTextDocumentProvider } from "./provider/textDocumentContentProv import { registerWebviewViewProvider } from "./provider/webviewViewProvider"; export function activate(context: ExtensionContext) { - // logging and debug features logger.info("activating"); + + // logging and debug features logger.register(context); - context.subscriptions.push(logger); registerSelectedTextHoverProvider(context); // prettify diagnostics feature diff --git a/apps/vscode-extension/src/logger.ts b/apps/vscode-extension/src/logger.ts index cf6251c..dd2bb65 100644 --- a/apps/vscode-extension/src/logger.ts +++ b/apps/vscode-extension/src/logger.ts @@ -128,6 +128,7 @@ function register(context: ExtensionContext) { ); } } + context.subscriptions.push({ dispose }); } export const logger = { From fd5161b944cf8c869d6ad865e9b84284620dab9e Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Sat, 3 Jan 2026 19:41:31 +0100 Subject: [PATCH 13/14] add instructions to export the logs and add them to github issues --- .github/ISSUE_TEMPLATE/bug_report.md | 21 +++++++++++++++------ docs/vscode-logs.md | 11 +++++++++++ docs/vscode-logs/1-output-window.png | Bin 0 -> 60825 bytes docs/vscode-logs/2-log-level.png | Bin 0 -> 24039 bytes docs/vscode-logs/4-export-logs.png | Bin 0 -> 41489 bytes docs/vscode-logs/5-add-logs-to-gh.png | Bin 0 -> 21892 bytes 6 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 docs/vscode-logs.md create mode 100644 docs/vscode-logs/1-output-window.png create mode 100644 docs/vscode-logs/2-log-level.png create mode 100644 docs/vscode-logs/4-export-logs.png create mode 100644 docs/vscode-logs/5-add-logs-to-gh.png diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 994e90e..4df199c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -6,18 +6,27 @@ labels: bug assignees: "" --- -**Describe the bug** +### **Describe the bug** + A clear and concise description of what the bug is. -**Expected behavior** +### **Expected behavior** + A clear and concise description of what you expected to happen. -**Original error** +### **Original error** + If this bug is related to an error that is not formatting well, please attach the original error in a code block: - + +``` Type 'number' is not assignable to type 'string'.ts(2322) - +``` + +### **Logs** + +Add the logs to help debugging what went wrong. See [these instructions](../../docs/hide-original-errors.md) on how to find and export the logs. + +### **Screenshots** -**Screenshots** If applicable, add screenshots to help explain your problem. diff --git a/docs/vscode-logs.md b/docs/vscode-logs.md new file mode 100644 index 0000000..9d2608c --- /dev/null +++ b/docs/vscode-logs.md @@ -0,0 +1,11 @@ +# Instructions to find and export the VS Code logs for Pretty TypeScript Errors + +1. Open the output window to the `Pretty TypeScript Errors` channel + ![Navigate to the `Pretty TypeScript Errors` output channel](./vscode-logs/1-output-window.png) +2. Set the log level of the `Pretty TypeScript Errors` output channel to `Trace` + ![Set the log level to `Trace`](vscode-logs/2-log-level.png) +3. **Reproduce your bug or error**, this should generate verbose logging output. +4. Either copy the output by selecting it or use one of the options in the menu shown: + ![Choose a method of copying or exporting the logs](vscode-logs/4-export-logs.png) +5. Either paste the output or add the logfile to the GitHub issue + ![Add the otuput to the GitHub issue](vscode-logs/5-add-logs-to-gh.png) diff --git a/docs/vscode-logs/1-output-window.png b/docs/vscode-logs/1-output-window.png new file mode 100644 index 0000000000000000000000000000000000000000..80761d78aadfa5b6709b90ff4cd5cbcb494f6942 GIT binary patch literal 60825 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 literal 0 HcmV?d00001 diff --git a/docs/vscode-logs/2-log-level.png b/docs/vscode-logs/2-log-level.png new file mode 100644 index 0000000000000000000000000000000000000000..fd8c87528f5d7dcacbb2df838addfa82d348fa95 GIT binary patch literal 24039 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 Mt-oKdP}d>k--r1U#sB~S literal 0 HcmV?d00001 diff --git a/docs/vscode-logs/4-export-logs.png b/docs/vscode-logs/4-export-logs.png new file mode 100644 index 0000000000000000000000000000000000000000..4c50706f509a6e743443f28207a0e901ce652a95 GIT binary patch literal 41489 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 literal 0 HcmV?d00001 diff --git a/docs/vscode-logs/5-add-logs-to-gh.png b/docs/vscode-logs/5-add-logs-to-gh.png new file mode 100644 index 0000000000000000000000000000000000000000..e9b4f16732eb40885dfd2ac7f4301e24144ec4d6 GIT binary patch literal 21892 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 EH}LMA!~g&Q literal 0 HcmV?d00001 From 1f1b22dc324c8a208bd706af84ef3cb308b58f9a Mon Sep 17 00:00:00 2001 From: kevin ramharak Date: Sat, 3 Jan 2026 19:50:38 +0100 Subject: [PATCH 14/14] add details element to github issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 4df199c..a50c016 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -27,6 +27,15 @@ Type 'number' is not assignable to type 'string'.ts(2322) Add the logs to help debugging what went wrong. See [these instructions](../../docs/hide-original-errors.md) on how to find and export the logs. +Either add it as an external file or put them in between these `
` tags below:
+
+
+Logs +
+ + + + ### **Screenshots** If applicable, add screenshots to help explain your problem.