From ca82bfcbf50f5d19275f24e7b098fe055098c25a Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 09:46:28 -0400 Subject: [PATCH 1/8] Update to version 0.3.25 --- tools/vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/vscode/package.json b/tools/vscode/package.json index e24d724c7..5cc9a05a8 100644 --- a/tools/vscode/package.json +++ b/tools/vscode/package.json @@ -7,7 +7,7 @@ "author": { "name": "UK AI Safety Institute" }, - "version": "0.3.24", + "version": "0.3.25", "license": "MIT", "homepage": "https://inspect.ai-safety-institute.org.uk/", "repository": { From 5782b24fe7eee6308d43d4bab5efd1bf7d3658d6 Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 09:48:35 -0400 Subject: [PATCH 2/8] poll for log files more frequently --- tools/vscode/src/providers/logview/logview-file-watcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/vscode/src/providers/logview/logview-file-watcher.ts b/tools/vscode/src/providers/logview/logview-file-watcher.ts index b5747b470..820e5db75 100644 --- a/tools/vscode/src/providers/logview/logview-file-watcher.ts +++ b/tools/vscode/src/providers/logview/logview-file-watcher.ts @@ -51,7 +51,7 @@ export class LogViewFileWatcher implements Disposable { } } } - }, 1000); + }, 500); } private lastEval_: number; private watchInterval_: NodeJS.Timeout; From 7a7313013a9c93d05fcc6238824cdc30650a50b4 Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 09:54:00 -0400 Subject: [PATCH 3/8] Remove deserialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don’t serialize state (and we in fact close an open viewer when the editor is re-opened/reloaded) --- tools/vscode/src/components/webview.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/tools/vscode/src/components/webview.ts b/tools/vscode/src/components/webview.ts index a5be98417..1858cce39 100644 --- a/tools/vscode/src/components/webview.ts +++ b/tools/vscode/src/components/webview.ts @@ -28,26 +28,13 @@ export class InspectWebviewManager, S> { ) => T ) { this.extensionUri_ = context.extensionUri; - - context.subscriptions.push( - window.registerWebviewPanelSerializer(this.viewType_, { - deserializeWebviewPanel: (panel, state: S) => { - this.restoreWebview(panel, state); - setTimeout(() => { - panel.dispose(); - }, 200); - return Promise.resolve(); - }, - }) - ); } public setOnShow(f: () => void) { this.onShow_ = f; } - public setOnClose(f: () => void) { - this.onClose_ = f; + public setOnClose(f: () => void) { this.onClose_ = f; } public showWebview(state: S, options?: ShowOptions): void { From e2ef7a75b8f1cc82daf1e8ce1d6bf6605e04b56d Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 09:56:22 -0400 Subject: [PATCH 4/8] Add positron viewer support This uses a generic host interface to show the viewer, allowing us to adapt to different IDEs. --- tools/vscode/.vscode/launch.json | 1 + tools/vscode/src/@types/hooks.d.ts | 77 ++++++++++++++++ tools/vscode/src/components/webview.ts | 48 ++++------ tools/vscode/src/extension.ts | 34 +++++-- tools/vscode/src/hooks/hooks.ts | 92 +++++++++++++++++++ tools/vscode/src/hooks/index.ts | 37 ++++++++ tools/vscode/src/hooks/preview.ts | 24 +++++ .../src/providers/logview/logview-manager.ts | 13 +-- .../src/providers/logview/logview-webview.ts | 32 +++++-- tools/vscode/src/providers/logview/logview.ts | 18 +++- 10 files changed, 319 insertions(+), 57 deletions(-) create mode 100644 tools/vscode/src/@types/hooks.d.ts create mode 100644 tools/vscode/src/hooks/hooks.ts create mode 100644 tools/vscode/src/hooks/index.ts create mode 100644 tools/vscode/src/hooks/preview.ts diff --git a/tools/vscode/.vscode/launch.json b/tools/vscode/.vscode/launch.json index c42edc04b..a614f634f 100644 --- a/tools/vscode/.vscode/launch.json +++ b/tools/vscode/.vscode/launch.json @@ -5,6 +5,7 @@ { "version": "0.2.0", "configurations": [ + { "name": "Run Extension", "type": "extensionHost", diff --git a/tools/vscode/src/@types/hooks.d.ts b/tools/vscode/src/@types/hooks.d.ts new file mode 100644 index 000000000..283e020df --- /dev/null +++ b/tools/vscode/src/@types/hooks.d.ts @@ -0,0 +1,77 @@ + + + +declare module 'positron' { + + import * as vscode from 'vscode'; + + export interface PositronApi { + version: string; + runtime: PositronRuntime; + languages: PositronLanguages; + window: PositronWindow; + } + + export interface PositronRuntime { + executeCode( + languageId: string, + code: string, + focus: boolean + ): Thenable; + } + + export interface PositronLanguages { + registerStatementRangeProvider( + selector: vscode.DocumentSelector, + provider: StatementRangeProvider + ): vscode.Disposable; + } + + export interface StatementRangeProvider { + provideStatementRange( + document: vscode.TextDocument, + position: vscode.Position, + token: vscode.CancellationToken + ): vscode.ProviderResult; + } + + export interface StatementRange { + readonly range: vscode.Range; + readonly code?: string; + } + + export interface PositronWindow { + createPreviewPanel( + viewType: string, + title: string, + preserveFocus?: boolean, + options?: PreviewOptions + ): PreviewPanel; + } + + export interface PreviewOptions { + readonly enableScripts?: boolean; + readonly enableForms?: boolean; + readonly localResourceRoots?: readonly vscode.Uri[]; + readonly portMapping?: readonly vscode.WebviewPortMapping[]; + } + + export interface PreviewPanel { + readonly viewType: string; + title: string; + readonly webview: vscode.Webview; + readonly active: boolean; + readonly visible: boolean; + readonly viewColumn: vscode.ViewColumn; + readonly onDidChangeViewState: vscode.Event; + readonly onDidDispose: vscode.Event; + reveal(preserveFocus?: boolean): void; + dispose(): any; + } + + export interface PreviewPanelOnDidChangeViewStateEvent { + readonly previewPanel: PreviewPanel; + } +} + + diff --git a/tools/vscode/src/components/webview.ts b/tools/vscode/src/components/webview.ts index 1858cce39..4b5d5f415 100644 --- a/tools/vscode/src/components/webview.ts +++ b/tools/vscode/src/components/webview.ts @@ -1,14 +1,8 @@ -import { - Uri, - WebviewPanel, - window, - ViewColumn, - EventEmitter, - ExtensionContext, -} from "vscode"; +import { Uri, ViewColumn, EventEmitter, ExtensionContext } from "vscode"; import { Disposable } from "../core/dispose"; import { getNonce } from "../core/nonce"; +import { ExtensionHost, HostWebviewPanel } from "../hooks"; export interface ShowOptions { readonly preserveFocus?: boolean; @@ -24,8 +18,9 @@ export class InspectWebviewManager, S> { private webviewType_: new ( context: ExtensionContext, state: S, - webviewPanel: WebviewPanel - ) => T + webviewPanel: HostWebviewPanel + ) => T, + private host_: ExtensionHost ) { this.extensionUri_ = context.extensionUri; } @@ -34,7 +29,8 @@ export class InspectWebviewManager, S> { this.onShow_ = f; } - public setOnClose(f: () => void) { this.onClose_ = f; + public setOnClose(f: () => void) { + this.onClose_ = f; } public showWebview(state: S, options?: ShowOptions): void { @@ -82,42 +78,37 @@ export class InspectWebviewManager, S> { } private preserveEditorFocus() { - // No need to take action here - we are already setting preserveFocus + // No need to take action here - we are already setting preserveFocus // and ensuring that focus ends up in the correct places } - private restoreWebview(panel: WebviewPanel, state: S): void { + private restoreWebview(panel: HostWebviewPanel, state: S): void { const view = new this.webviewType_(this.context, state, panel); this.registerWebviewListeners(view); this.activeView_ = view; } - private createWebview( context: ExtensionContext, state: S, showOptions?: ShowOptions ): T { - - const webview = window.createWebviewPanel( + const previewPanel = this.host_.createPreviewPanel( this.viewType_, this.title_, - { - viewColumn: showOptions?.viewColumn || ViewColumn.Beside, - preserveFocus: showOptions?.preserveFocus, - }, + showOptions?.preserveFocus, { enableScripts: true, enableForms: true, retainContextWhenHidden: true, localResourceRoots: [ ...this.localResourceRoots, - Uri.joinPath(context.extensionUri, "assets", "www") + Uri.joinPath(context.extensionUri, "assets", "www"), ], } ); - const inspectWebView = new this.webviewType_(context, state, webview); + const inspectWebView = new this.webviewType_(context, state, previewPanel); return inspectWebView; } @@ -156,7 +147,7 @@ export class InspectWebviewManager, S> { } export abstract class InspectWebview extends Disposable { - protected readonly _webviewPanel: WebviewPanel; + protected readonly _webviewPanel: HostWebviewPanel; private readonly _onDidDispose = this._register(new EventEmitter()); public readonly onDispose = this._onDidDispose.event; @@ -164,7 +155,7 @@ export abstract class InspectWebview extends Disposable { public constructor( private readonly context: ExtensionContext, state: T, - webviewPanel: WebviewPanel + webviewPanel: HostWebviewPanel ) { super(); @@ -199,7 +190,8 @@ export abstract class InspectWebview extends Disposable { protected abstract getHtml(state: T): string; protected getExtensionVersion(): string { - return (this.context.extension.packageJSON as Record).version as string; + return (this.context.extension.packageJSON as Record) + .version as string; } protected webviewHTML( @@ -248,7 +240,8 @@ export abstract class InspectWebview extends Disposable { font-src ${this._webviewPanel.webview.cspSource}; style-src ${this._webviewPanel.webview.cspSource} ${allowUnsafe ? "'unsafe-inline'" : "" }; - script-src 'nonce-${nonce}' ${allowUnsafe ? "'unsafe-eval'" : ""}; + script-src 'nonce-${nonce}' ${allowUnsafe ? "'unsafe-eval'" : "" + }; connect-src ${this._webviewPanel.webview.cspSource} ; frame-src *; "> @@ -281,5 +274,4 @@ export abstract class InspectWebview extends Disposable { protected escapeAttribute(value: string | Uri): string { return value.toString().replace(/"/g, """); } - -} \ No newline at end of file +} diff --git a/tools/vscode/src/extension.ts b/tools/vscode/src/extension.ts index f5247640b..3c6adc4fe 100644 --- a/tools/vscode/src/extension.ts +++ b/tools/vscode/src/extension.ts @@ -12,7 +12,10 @@ import { activateEvalManager } from "./providers/inspect/inspect-eval"; import { activateActivityBar } from "./providers/activity-bar/activity-bar-provider"; import { activateActiveTaskProvider } from "./providers/active-task/active-task-provider"; import { activateWorkspaceTaskProvider } from "./providers/workspace/workspace-task-provider"; -import { WorkspaceStateManager, activateWorkspaceState } from "./providers/workspace/workspace-state-provider"; +import { + WorkspaceStateManager, + activateWorkspaceState, +} from "./providers/workspace/workspace-state-provider"; import { initializeWorkspace } from "./providers/workspace/workspace-init"; import { activateWorkspaceEnv } from "./providers/workspace/workspace-env-provider"; import { initPythonInterpreter } from "./core/python"; @@ -20,18 +23,21 @@ import { initInspectProps } from "./inspect"; import { activateInspectManager } from "./providers/inspect/inspect-manager"; import { checkActiveWorkspaceFolder } from "./core/workspace"; import { inspectBinPath, inspectVersion } from "./inspect/props"; +import { extensionHost } from "./hooks"; const kInspectMinimumVersion = "0.3.8"; // This method is called when your extension is activated // Your extension is activated the very first time the command is executed export async function activate(context: ExtensionContext) { - // we don't activate anything if there is no workspace if (!checkActiveWorkspaceFolder()) { return; } + // Get the host + const host = extensionHost(); + const commandManager = new CommandManager(); // init python interpreter @@ -62,14 +68,23 @@ export async function activate(context: ExtensionContext) { context.subscriptions.push(inspectManager); // Eval Manager - const [inspectEvalCommands, inspectEvalMgr] = await activateEvalManager(stateManager, context); + const [inspectEvalCommands, inspectEvalMgr] = await activateEvalManager( + stateManager, + context + ); // Activate a watcher which inspects the active document and determines // the active task (if any) - const [taskCommands, activeTaskManager] = activateActiveTaskProvider(inspectEvalMgr, context); + const [taskCommands, activeTaskManager] = activateActiveTaskProvider( + inspectEvalMgr, + context + ); // Active the workspace manager to watch for tasks - const workspaceTaskMgr = activateWorkspaceTaskProvider(inspectManager, context); + const workspaceTaskMgr = activateWorkspaceTaskProvider( + inspectManager, + context + ); // Read the extension configuration const settingsMgr = new InspectSettingsManager(() => { @@ -90,7 +105,8 @@ export async function activate(context: ExtensionContext) { inspectManager, settingsMgr, workspaceEnvManager, - context + context, + host ); const inspectLogviewManager = logviewWebviewManager; @@ -106,7 +122,6 @@ export async function activate(context: ExtensionContext) { context ); - // Register the log view link provider window.registerTerminalLinkProvider( logviewTerminalLinkProvider(logviewWebviewManager) @@ -127,7 +142,7 @@ export async function activate(context: ExtensionContext) { ...taskBarCommands, ...stateCommands, ...envComands, - ...taskCommands + ...taskCommands, ].forEach((cmd) => commandManager.register(cmd)); context.subscriptions.push(commandManager); @@ -164,7 +179,6 @@ const checkInspectVersion = async () => { if (inspectBinPath()) { const version = inspectVersion(); if (version && version.compare(kInspectMinimumVersion) === -1) { - const close: MessageItem = { title: "Close" }; await window.showInformationMessage( "The VS Code extension requires a newer version of Inspect. Please update " + @@ -173,4 +187,4 @@ const checkInspectVersion = async () => { ); } } -}; \ No newline at end of file +}; diff --git a/tools/vscode/src/hooks/hooks.ts b/tools/vscode/src/hooks/hooks.ts new file mode 100644 index 000000000..30b3f1524 --- /dev/null +++ b/tools/vscode/src/hooks/hooks.ts @@ -0,0 +1,92 @@ +import * as vscode from "vscode"; +import * as hooks from "positron"; + +import { ExtensionHost, HostWebviewPanel } from "."; +import { PreviewPanelOnDidChangeViewStateEvent } from "positron"; + +declare global { + function acquirePositronApi(): hooks.PositronApi; +} + +let api: hooks.PositronApi | null | undefined; + +export function hooksApi(): hooks.PositronApi | undefined | null { + if (api === undefined) { + try { + api = acquirePositronApi(); + } catch { + api = null; + } + } + return api; +} + +export function hasHooks() { + return !!hooksApi(); +} + +export function hooksExtensionHost(): ExtensionHost { + return { + createPreviewPanel: ( + viewType: string, + title: string, + preserveFocus?: boolean, + options?: vscode.WebviewPanelOptions & vscode.WebviewOptions + ): HostWebviewPanel => { + // create preview panel + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + const panel = hooksApi()?.window.createPreviewPanel( + viewType, + title, + preserveFocus, + { + enableScripts: options?.enableScripts, + enableForms: options?.enableForms, + localResourceRoots: options?.localResourceRoots, + portMapping: options?.portMapping, + } + )!; + + // adapt to host interface + return new HookWebviewPanel(panel); + }, + }; +} + +// This panel provides the base interface than any host can provide in order for +// our log viewer to work properly. It can be provided by vscode using the defaulthost +// or the hooksExtensionHost if the positron api is detected +class HookWebviewPanel implements HostWebviewPanel { + onDidChangeViewState: vscode.Event; + onDidDispose: vscode.Event; + + constructor(private readonly panel_: hooks.PreviewPanel) { + this.onDidChangeViewState = this.panel_.onDidChangeViewState; + this.onDidDispose = this.panel_.onDidDispose; + } + + get webview() { + return this.panel_.webview; + } + + get visible() { + return this.panel_.visible; + } + + get active() { + return this.panel_.active; + } + + get viewColumn() { + return vscode.ViewColumn.Two; + } + + + reveal(_viewColumn?: vscode.ViewColumn, preserveFocus?: boolean) { + this.panel_.reveal(preserveFocus); + } + + dispose() { + this.panel_.dispose(); + } +} diff --git a/tools/vscode/src/hooks/index.ts b/tools/vscode/src/hooks/index.ts new file mode 100644 index 000000000..c8581162f --- /dev/null +++ b/tools/vscode/src/hooks/index.ts @@ -0,0 +1,37 @@ +import vscode, { WebviewPanelOptions, WebviewOptions } from "vscode"; +import { createPreviewPanel } from "./preview"; +import { hasHooks, hooksExtensionHost } from "./hooks"; + +export interface HostWebviewPanel extends vscode.Disposable { + readonly webview: vscode.Webview; + readonly active: boolean; + readonly visible: boolean; + readonly viewColumn: vscode.ViewColumn; + reveal(viewColumn?: vscode.ViewColumn, preserveFocus?: boolean): void; + readonly onDidChangeViewState: vscode.Event; + readonly onDidDispose: vscode.Event; +} + +export interface ExtensionHost { + // preview + createPreviewPanel( + viewType: string, + title: string, + preserveFocus?: boolean, + options?: WebviewPanelOptions & WebviewOptions + ): HostWebviewPanel; +} + +export function extensionHost(): ExtensionHost { + if (hasHooks()) { + return hooksExtensionHost(); + } else { + return defaultExtensionHost(); + } +} + +function defaultExtensionHost(): ExtensionHost { + return { + createPreviewPanel, + }; +} diff --git a/tools/vscode/src/hooks/preview.ts b/tools/vscode/src/hooks/preview.ts new file mode 100644 index 000000000..80eaa29e3 --- /dev/null +++ b/tools/vscode/src/hooks/preview.ts @@ -0,0 +1,24 @@ +import { + window, + WebviewOptions, + WebviewPanelOptions, + ViewColumn, +} from "vscode"; +import { HostWebviewPanel } from "."; + +export function createPreviewPanel( + viewType: string, + title: string, + preserveFocus?: boolean, + options?: WebviewPanelOptions & WebviewOptions +): HostWebviewPanel { + return window.createWebviewPanel( + viewType, + title, + { + viewColumn: ViewColumn.Beside, + preserveFocus, + }, + options + ) as HostWebviewPanel; +} diff --git a/tools/vscode/src/providers/logview/logview-manager.ts b/tools/vscode/src/providers/logview/logview-manager.ts index e06d6b433..3c8e48832 100644 --- a/tools/vscode/src/providers/logview/logview-manager.ts +++ b/tools/vscode/src/providers/logview/logview-manager.ts @@ -5,17 +5,21 @@ import { WorkspaceEnvManager } from "../workspace/workspace-env-provider"; import { activeWorkspaceFolder } from "../../core/workspace"; import { workspacePath } from "../../core/path"; import { kInspectEnvValues } from "../inspect/inspect-constants"; - +import { ExtensionHost } from "../../hooks"; export class InspectLogviewManager { constructor( private readonly webViewManager_: InspectLogviewWebviewManager, private readonly settingsMgr_: InspectSettingsManager, - private readonly envMgr_: WorkspaceEnvManager + private readonly envMgr_: WorkspaceEnvManager, + private readonly host_: ExtensionHost ) { } public async showLogFile(logFile: Uri) { - if (this.settingsMgr_.getSettings().logViewType === "text" && logFile.scheme === "file") { + if ( + this.settingsMgr_.getSettings().logViewType === "text" && + logFile.scheme === "file" + ) { await workspace.openTextDocument(logFile).then(async (doc) => { await window.showTextDocument(doc, { preserveFocus: true, @@ -23,14 +27,12 @@ export class InspectLogviewManager { }); }); } else { - // Show the log file this.webViewManager_.showLogFile(logFile); } } public showInspectView() { - // See if there is a log dir const envVals = this.envMgr_.getValues(); const env_log = envVals[kInspectEnvValues.logDir]; @@ -53,4 +55,3 @@ export class InspectLogviewManager { return this.webViewManager_.viewColumn(); } } - diff --git a/tools/vscode/src/providers/logview/logview-webview.ts b/tools/vscode/src/providers/logview/logview-webview.ts index 92e642a7b..31d949be9 100644 --- a/tools/vscode/src/providers/logview/logview-webview.ts +++ b/tools/vscode/src/providers/logview/logview-webview.ts @@ -6,9 +6,8 @@ import { MessageItem, Uri, ViewColumn, - WebviewPanel, env, - window + window, } from "vscode"; import { @@ -39,6 +38,7 @@ import { InspectManager, } from "../inspect/inspect-manager"; import { LogviewState } from "./commands"; +import { ExtensionHost, HostWebviewPanel } from "../../hooks"; const kLogViewId = "inspect.logview"; @@ -46,7 +46,11 @@ export class InspectLogviewWebviewManager extends InspectWebviewManager< InspectLogviewWebview, LogviewState > { - constructor(inspectManager: InspectManager, context: ExtensionContext) { + constructor( + inspectManager: InspectManager, + context: ExtensionContext, + host: ExtensionHost + ) { // If the interpreter changes, refresh the tasks context.subscriptions.push( inspectManager.onInspectChanged((e: InspectChangedEvent) => { @@ -67,7 +71,8 @@ export class InspectLogviewWebviewManager extends InspectWebviewManager< kLogViewId, "Inspect View", localResourceRoots, - InspectLogviewWebview + InspectLogviewWebview, + host ); this.lastState_; } @@ -164,7 +169,7 @@ class InspectLogviewWebview extends InspectWebview { public constructor( context: ExtensionContext, state: LogviewState, - webviewPanel: WebviewPanel + webviewPanel: HostWebviewPanel ) { super(context, state, webviewPanel); @@ -188,7 +193,10 @@ class InspectLogviewWebview extends InspectWebview { try { await window.showTextDocument(Uri.file(file.path)); } catch (err) { - if (err instanceof Error && err.name === "CodeExpectedError") { + if ( + err instanceof Error && + err.name === "CodeExpectedError" + ) { const close: MessageItem = { title: "Close" }; await window.showInformationMessage( "This file is too large to be opened by the viewer.", @@ -254,7 +262,12 @@ class InspectLogviewWebview extends InspectWebview { type: "updateState", url: state?.log_file?.toString(), }; - const stateScript = state && state.log_file ? `` : ""; + const stateScript = + state && state.log_file + ? `` + : ""; // add content security policy indexHtml = indexHtml.replace( @@ -263,7 +276,8 @@ class InspectLogviewWebview extends InspectWebview { ${stateScript} @@ -364,7 +378,7 @@ function evalLogHeaders(files: string[]) { } export function webviewPanelJsonRpcServer( - webviewPanel: WebviewPanel, + webviewPanel: HostWebviewPanel, methods: | Record | ((name: string) => JsonRpcServerMethod | undefined) diff --git a/tools/vscode/src/providers/logview/logview.ts b/tools/vscode/src/providers/logview/logview.ts index 1eca67a3f..e3bc83c2d 100644 --- a/tools/vscode/src/providers/logview/logview.ts +++ b/tools/vscode/src/providers/logview/logview.ts @@ -7,17 +7,27 @@ import { InspectLogviewManager } from "./logview-manager"; import { InspectSettingsManager } from "../settings/inspect-settings"; import { InspectManager } from "../inspect/inspect-manager"; import { WorkspaceEnvManager } from "../workspace/workspace-env-provider"; +import { ExtensionHost } from "../../hooks"; export async function activateLogview( inspectManager: InspectManager, settingsMgr: InspectSettingsManager, envMgr: WorkspaceEnvManager, - context: ExtensionContext + context: ExtensionContext, + host: ExtensionHost ): Promise<[Command[], InspectLogviewManager]> { - // initilize manager - const logviewWebManager = new InspectLogviewWebviewManager(inspectManager, context); - const logviewManager = new InspectLogviewManager(logviewWebManager, settingsMgr, envMgr); + const logviewWebManager = new InspectLogviewWebviewManager( + inspectManager, + context, + host + ); + const logviewManager = new InspectLogviewManager( + logviewWebManager, + settingsMgr, + envMgr, + host + ); // logview commands return [await logviewCommands(logviewManager), logviewManager]; From 6815a9b89d6550f8a03306c3cb43ed80bed85ce5 Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 09:57:02 -0400 Subject: [PATCH 5/8] Update changelog --- tools/vscode/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/vscode/CHANGELOG.md b/tools/vscode/CHANGELOG.md index ca69ffd14..1918cb081 100644 --- a/tools/vscode/CHANGELOG.md +++ b/tools/vscode/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.3.25 + +- Poll more frequently to show new log files +- Add support for showing the log viewer in the Positron Viewer + ## 0.3.24 - Properly deal with URI encoded characters in log directories when opening a log file From ec7e04ead266673ff4fc3f91d8a2ae0e016e56e3 Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 10:42:30 -0400 Subject: [PATCH 6/8] Avoid scrollbars on windows when showing progress --- src/inspect_ai/_view/www/App.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inspect_ai/_view/www/App.css b/src/inspect_ai/_view/www/App.css index 5e243f91f..a74eff7ea 100644 --- a/src/inspect_ai/_view/www/App.css +++ b/src/inspect_ai/_view/www/App.css @@ -634,7 +634,7 @@ table.table.table-sm td { margin-left: 0; } to { - margin-left: 100%; + margin-left: 95%; } } From 70c01e3d4f4eaa69f686ae122eec02c752584b6c Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 13:44:47 -0400 Subject: [PATCH 7/8] Improve wrapping behavarior of scores --- src/inspect_ai/_view/www/App.css | 12 ++++++++++++ src/inspect_ai/_view/www/src/navbar/Navbar.mjs | 10 +--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/inspect_ai/_view/www/App.css b/src/inspect_ai/_view/www/App.css index a74eff7ea..4dbe1de9b 100644 --- a/src/inspect_ai/_view/www/App.css +++ b/src/inspect_ai/_view/www/App.css @@ -216,6 +216,18 @@ body { background-color: var(--bs-light); } +.navbar-title-grid { + display: grid; + grid-template-columns: 1fr; + width: 100%; +} + +@media (min-width: 575px) { + .navbar-title-grid { + grid-template-columns: 1fr auto; + } +} + [data-bs-theme="dark"] .navbar { background-color: unset; } diff --git a/src/inspect_ai/_view/www/src/navbar/Navbar.mjs b/src/inspect_ai/_view/www/src/navbar/Navbar.mjs index ecedc3787..4524520f6 100644 --- a/src/inspect_ai/_view/www/src/navbar/Navbar.mjs +++ b/src/inspect_ai/_view/www/src/navbar/Navbar.mjs @@ -138,15 +138,7 @@ export const Navbar = ({ borderBottom: "solid var(--bs-border-color) 1px", }} > -
- ${navbarContents} -
+ `; }; From 24eac16b9d8165190f78c5ffeddbacdbfa0429fb Mon Sep 17 00:00:00 2001 From: Charles Teague Date: Wed, 31 Jul 2024 15:46:52 -0400 Subject: [PATCH 8/8] Revert "Remove deserialization" This reverts commit 7a7313013a9c93d05fcc6238824cdc30650a50b4. --- tools/vscode/src/components/webview.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/vscode/src/components/webview.ts b/tools/vscode/src/components/webview.ts index 4b5d5f415..7c0d10136 100644 --- a/tools/vscode/src/components/webview.ts +++ b/tools/vscode/src/components/webview.ts @@ -1,4 +1,4 @@ -import { Uri, ViewColumn, EventEmitter, ExtensionContext } from "vscode"; +import { Uri, ViewColumn, EventEmitter, ExtensionContext, window } from "vscode"; import { Disposable } from "../core/dispose"; import { getNonce } from "../core/nonce"; @@ -23,6 +23,18 @@ export class InspectWebviewManager, S> { private host_: ExtensionHost ) { this.extensionUri_ = context.extensionUri; + + context.subscriptions.push( + window.registerWebviewPanelSerializer(this.viewType_, { + deserializeWebviewPanel: (panel) => { + //this.restoreWebview(panel as HostWebviewPanel, state); + setTimeout(() => { + panel.dispose(); + }, 200); + return Promise.resolve(); + }, + }) + ); } public setOnShow(f: () => void) {