Skip to content

Commit 8f7ccb8

Browse files
feat(vscode): watchdog status bar, post-mortem viewer, session browser, live stream (v0.2.0)
#117 — WatchdogStatusBar in statusBar.ts - Polls meta.json for watchdog_timeout_seconds / watchdog_budget_dollars - Shows elapsed/budget in status bar while session is active - Switches to red error state when watchdog-postmortem.json appears - Configurable poll interval via agentTrace.watchdogPollIntervalSeconds - Disposed cleanly on session end and extension deactivation #118 — PostMortemManager in postMortem.ts - Watches all session directories for new watchdog-postmortem.json files - Auto-opens a formatted webview panel when a post-mortem appears - Shows reason, cost at death, wall time, last tool call, last LLM response - 'Copy recovery context' button copies to clipboard for follow-up sessions - openForSession() command for manual access from command palette #119 — SessionTreeProvider in sessionTree.ts - TreeDataProvider showing all sessions grouped by date (Today/Yesterday/date) - Each session shows: short ID, cost, status icon, task name - Status: completed ✓, watchdog ⚠, error ✗, in_progress ⟳ - Auto-refreshes via fs.watch + configurable polling interval - Context menu: 'View Post-Mortem' for watchdog-terminated sessions - Registered as agentTrace.sessionBrowser in Explorer sidebar #120 — LiveStreamPanel in liveStream.ts - Webview connecting to agent-strace server via SSE (EventSource API) - Real-time event feed with type-coloured rows, timestamp, session link - Filter by event type, pause/resume, clear, max 500 events in DOM - Exponential backoff reconnection (1s → 2s → 4s … capped at 30s) - 'Jump to session' link posts message to reveal in session browser - Shows configuration prompt when agentTrace.collectorEndpoint is unset package.json: version 0.1.2 → 0.2.0, new commands, views, menus, settings Co-authored-by: Ona <no-reply@ona.com>
1 parent a160e87 commit 8f7ccb8

6 files changed

Lines changed: 1130 additions & 7 deletions

File tree

vscode-extension/package.json

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "agent-strace",
33
"displayName": "agent-strace",
44
"description": "Live session overlay for agent-strace: status bar, gutter annotations, and event stream panel.",
5-
"version": "0.1.2",
5+
"version": "0.2.0",
66
"publisher": "Siddhant-K-code",
77
"license": "MIT",
88
"repository": {
@@ -21,6 +21,25 @@
2121
"main": "./out/extension.js",
2222
"contributes": {
2323
"commands": [
24+
{
25+
"command": "agentTrace.openLiveStream",
26+
"title": "agent-trace: Open Live Stream",
27+
"icon": "$(broadcast)"
28+
},
29+
{
30+
"command": "agentTrace.openPostMortem",
31+
"title": "agent-trace: View Post-Mortem",
32+
"icon": "$(file-text)"
33+
},
34+
{
35+
"command": "agentTrace.refreshSessionBrowser",
36+
"title": "agent-trace: Refresh Session Browser",
37+
"icon": "$(refresh)"
38+
},
39+
{
40+
"command": "agentTrace.revealSession",
41+
"title": "agent-trace: Reveal Session in Browser"
42+
},
2443
{
2544
"command": "agentTrace.pauseAgent",
2645
"title": "agent-trace: Pause Agent",
@@ -47,6 +66,32 @@
4766
"id": "agentTrace.eventStream",
4867
"name": "Agent Trace",
4968
"when": "agentTrace.sessionActive"
69+
},
70+
{
71+
"id": "agentTrace.sessionBrowser",
72+
"name": "Agent Trace Sessions",
73+
"when": "workspaceContains:.agent-traces"
74+
}
75+
]
76+
},
77+
"menus": {
78+
"view/title": [
79+
{
80+
"command": "agentTrace.refreshSessionBrowser",
81+
"when": "view == agentTrace.sessionBrowser",
82+
"group": "navigation"
83+
},
84+
{
85+
"command": "agentTrace.openLiveStream",
86+
"when": "view == agentTrace.sessionBrowser",
87+
"group": "navigation"
88+
}
89+
],
90+
"view/item/context": [
91+
{
92+
"command": "agentTrace.openPostMortem",
93+
"when": "view == agentTrace.sessionBrowser && viewItem == sessionWithPostMortem",
94+
"group": "inline"
5095
}
5196
]
5297
},
@@ -67,6 +112,21 @@
67112
"type": "boolean",
68113
"default": true,
69114
"description": "Show inline read/write counts at the top of agent-touched files."
115+
},
116+
"agentTrace.watchdogPollIntervalSeconds": {
117+
"type": "number",
118+
"default": 5,
119+
"description": "How often (in seconds) the watchdog status bar polls for cost and elapsed time."
120+
},
121+
"agentTrace.collectorEndpoint": {
122+
"type": "string",
123+
"default": "",
124+
"description": "Remote agent-strace server endpoint (e.g. http://collector:4317). Leave empty to use local .agent-traces/."
125+
},
126+
"agentTrace.sessionBrowserRefreshInterval": {
127+
"type": "number",
128+
"default": 5,
129+
"description": "How often (in seconds) the session browser tree view refreshes."
70130
}
71131
}
72132
}

vscode-extension/src/extension.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import * as vscode from "vscode";
1111
import { DecorationManager } from "./decorations";
1212
import { EventStreamPanel } from "./panel";
1313
import { PauseManager } from "./pauseAgent";
14-
import { StatusBarManager } from "./statusBar";
14+
import { LiveStreamPanel } from "./liveStream";
15+
import { PostMortemManager } from "./postMortem";
16+
import { SessionTreeProvider } from "./sessionTree";
17+
import { StatusBarManager, WatchdogStatusBar } from "./statusBar";
1518
import { TraceWatcher } from "./traceStore";
1619

1720
export function activate(context: vscode.ExtensionContext): void {
@@ -30,9 +33,13 @@ export function activate(context: vscode.ExtensionContext): void {
3033

3134
const watcher = new TraceWatcher(workspaceRoot, traceDirSetting);
3235
const statusBar = new StatusBarManager();
36+
const watchdogBar = new WatchdogStatusBar();
3337
const decorations = new DecorationManager();
3438
const pauseManager = new PauseManager(traceDir);
3539
const panel = new EventStreamPanel(context.extensionUri);
40+
const postMortem = new PostMortemManager(traceDir);
41+
const liveStream = new LiveStreamPanel(context.extensionUri);
42+
const sessionTree = new SessionTreeProvider(traceDir);
3643

3744
// -------------------------------------------------------------------------
3845
// Webview panel registration
@@ -55,6 +62,7 @@ export function activate(context: vscode.ExtensionContext): void {
5562
true
5663
);
5764
statusBar.update(state);
65+
watchdogBar.onSessionStart(traceDir, state);
5866
decorations.update(state);
5967
panel.onSessionStart(state);
6068
});
@@ -66,13 +74,15 @@ export function activate(context: vscode.ExtensionContext): void {
6674
false
6775
);
6876
statusBar.update(null);
77+
watchdogBar.onSessionEnd();
6978
decorations.update(null);
7079
panel.onSessionEnd(state);
7180
pauseManager.cleanup();
7281
});
7382

7483
watcher.onStateChange((state) => {
7584
statusBar.update(state);
85+
watchdogBar.onStateChange(state);
7686
if (config.get<boolean>("showGutterAnnotations", true)) {
7787
decorations.update(state);
7888
}
@@ -141,8 +151,42 @@ export function activate(context: vscode.ExtensionContext): void {
141151

142152
watcher.start();
143153

154+
// Register session browser tree view
155+
const treeView = vscode.window.registerTreeDataProvider(
156+
"agentTrace.sessionBrowser",
157+
sessionTree
158+
);
159+
160+
// Register commands for new features
161+
context.subscriptions.push(
162+
vscode.commands.registerCommand("agentTrace.openLiveStream", () => {
163+
liveStream.open();
164+
}),
165+
vscode.commands.registerCommand("agentTrace.openPostMortem", (sessionId?: string) => {
166+
if (sessionId) {
167+
postMortem.openForSession(sessionId);
168+
} else {
169+
// Prompt user to pick a session
170+
vscode.window.showInputBox({ prompt: "Enter session ID" }).then((id) => {
171+
if (id) { postMortem.openForSession(id); }
172+
});
173+
}
174+
}),
175+
vscode.commands.registerCommand("agentTrace.refreshSessionBrowser", () => {
176+
sessionTree.refresh();
177+
}),
178+
vscode.commands.registerCommand("agentTrace.revealSession", (sessionId: string) => {
179+
// Refresh tree and let the user find the session
180+
sessionTree.refresh();
181+
})
182+
);
183+
184+
// Start post-mortem watcher
185+
postMortem.start();
186+
144187
// Register disposables
145-
context.subscriptions.push(watcher, statusBar, decorations);
188+
context.subscriptions.push(watcher, statusBar, watchdogBar, decorations,
189+
postMortem, liveStream, treeView, { dispose: () => sessionTree.dispose() });
146190
}
147191

148192
export function deactivate(): void {

0 commit comments

Comments
 (0)