From 9391177e860d10c4fbfc92da4584386d5efe8788 Mon Sep 17 00:00:00 2001 From: 11suixing11 <169120515+11suixing11@users.noreply.github.com> Date: Tue, 28 Jul 2026 12:07:47 +0800 Subject: [PATCH] fix: show report click feedback and log path --- package.json | 6 ++++++ src/extension.ts | 29 +++++++++++++++++++++-------- src/test/parser.test.ts | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index a1974ca..a56732a 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,12 @@ "when": "view == stacktale.reports && viewItem == report", "group": "inline" } + ], + "commandPalette": [ + { + "command": "stacktale.copyForAI", + "when": "false" + } ] }, "configuration": { diff --git a/src/extension.ts b/src/extension.ts index 0838615..bc3381e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -5,8 +5,10 @@ import { parseReports, StReport } from "./stParser"; export function activate(context: vscode.ExtensionContext): void { const provider = new ReportsProvider(); + const reportsView = vscode.window.createTreeView("stacktale.reports", { treeDataProvider: provider }); + provider.bindView(reportsView); context.subscriptions.push( - vscode.window.createTreeView("stacktale.reports", { treeDataProvider: provider }), + reportsView, vscode.commands.registerCommand("stacktale.refresh", () => provider.refresh()), vscode.commands.registerCommand("stacktale.openReport", (report: StReport) => openCulprit(report)), vscode.commands.registerCommand("stacktale.copyForAI", (item?: ReportItem) => copyForAI(item)), @@ -37,8 +39,13 @@ async function locateLogFile(): Promise { class ReportsProvider implements vscode.TreeDataProvider { private readonly changed = new vscode.EventEmitter(); + private view?: vscode.TreeView; readonly onDidChangeTreeData = this.changed.event; + bindView(view: vscode.TreeView): void { + this.view = view; + } + refresh(): void { this.changed.fire(); } @@ -50,8 +57,10 @@ class ReportsProvider implements vscode.TreeDataProvider { async getChildren(): Promise { const file = await locateLogFile(); if (!file || !fs.existsSync(file)) { + this.setDescription(undefined); return [ReportItem.note("No errors-ai.log in this workspace yet.")]; } + this.setDescription(vscode.workspace.asRelativePath(file, false)); let content: string; try { content = fs.readFileSync(file, "utf8"); @@ -64,6 +73,12 @@ class ReportsProvider implements vscode.TreeDataProvider { } return reports.map((r) => ReportItem.report(r)); } + + private setDescription(description: string | undefined): void { + if (this.view) { + this.view.description = description; + } + } } class ReportItem extends vscode.TreeItem { @@ -88,13 +103,11 @@ class ReportItem extends vscode.TreeItem { : `#${report.id}`; item.contextValue = "report"; item.iconPath = new vscode.ThemeIcon("bug"); - if (report.culprit) { - item.command = { - command: "stacktale.openReport", - title: "Open culprit", - arguments: [report], - }; - } + item.command = { + command: "stacktale.openReport", + title: "Open report", + arguments: [report], + }; return item; } } diff --git a/src/test/parser.test.ts b/src/test/parser.test.ts index bfa2f2d..1b5759a 100644 --- a/src/test/parser.test.ts +++ b/src/test/parser.test.ts @@ -49,3 +49,18 @@ test("ignores the file header's mid-line quote of the delimiter", () => { assert.equal(reports.length, 1); assert.equal(reports[0].id, "bbbb2222"); }); + +test("keeps reports that do not contain a source frame", () => { + const content = [ + "━━━ ERROR #cccc3333 ━━━ 2026-07-10 12:00:00.000 thread=main ━━━", + "ERROR (no exception): payment timed out", + "env: app=shop-api 1.4.2 | java 21 | prod", + "━━━ END #cccc3333 ━━━", + ].join("\n"); + + const reports = parseReports(content); + assert.equal(reports.length, 1); + assert.equal(reports[0].id, "cccc3333"); + assert.equal(reports[0].frames.length, 0); + assert.equal(reports[0].culprit, undefined); +});