{
+ try {
+ await vscode.commands.executeCommand(`workbench.view.extension.${VIEW_CONTAINER}`);
+ await vscode.commands.executeCommand(`${VIEW_CATALOG}.focus`);
+ } catch (e) {
+ log('error', e instanceof Error ? e.message : String(e));
+ void vscode.window.showErrorMessage('Could not open the Catalog panel.');
+ }
+}
+
+function openSkillBrowserWeb(): void {
+ void vscode.env.openExternal(vscode.Uri.parse(SKILL_BROWSER_URL));
+}
+
function asModuleTreeItem(item: unknown): ModuleTreeItem | undefined {
return item instanceof ModuleTreeItem ? item : undefined;
}
diff --git a/extension/src/views/catalogWebviewProvider.ts b/extension/src/views/catalogWebviewProvider.ts
index e84b5aa..db78a4b 100644
--- a/extension/src/views/catalogWebviewProvider.ts
+++ b/extension/src/views/catalogWebviewProvider.ts
@@ -1,6 +1,7 @@
import * as vscode from 'vscode';
import * as fs from 'node:fs';
import * as path from 'node:path';
+import { SKILL_BROWSER_URL } from '../constants.js';
import { requireWorkspace } from '../services/workspaceService.js';
import { applyGithubTokenFromSettings } from '../services/configService.js';
import { prepareWebviewHtml } from '../utils/webview.js';
@@ -30,6 +31,10 @@ export class CatalogWebviewProvider implements vscode.WebviewViewProvider {
}
webviewView.webview.onDidReceiveMessage(async (msg: { type: string; id?: string; text?: string }) => {
+ if (msg.type === 'openSkillBrowser') {
+ await vscode.env.openExternal(vscode.Uri.parse(SKILL_BROWSER_URL));
+ return;
+ }
if (msg.type === 'copy' && msg.text) {
await vscode.env.clipboard.writeText(msg.text);
void webviewView.webview.postMessage({ type: 'toast', text: 'Copied!' });
diff --git a/extension/webview-ui/main.ts b/extension/webview-ui/main.ts
index a6f88d0..7b07b8b 100644
--- a/extension/webview-ui/main.ts
+++ b/extension/webview-ui/main.ts
@@ -57,6 +57,22 @@ app.innerHTML = `
border-color: var(--vscode-focusBorder, #007fd4);
}
select { min-width: 7.5rem; }
+ .header-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ margin-bottom: 4px;
+ }
+ .header-row a {
+ font-size: 0.85em;
+ color: var(--vscode-textLink-foreground);
+ text-decoration: none;
+ white-space: nowrap;
+ }
+ .header-row a:hover {
+ text-decoration: underline;
+ }
.meta {
display: flex;
justify-content: space-between;
@@ -128,7 +144,10 @@ app.innerHTML = `
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
}
- Catalog
+