Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
{
"id": "amicode.runInspector",
"name": "Run Inspector",
"type": "webview"
"type": "webview",
"when": "amicode.inspectorRevealed"
}
]
},
Expand Down Expand Up @@ -114,8 +115,8 @@
"properties": {
"amicode.inspector.autoOpen": {
"type": "boolean",
"default": true,
"description": "Automatically reveal the Run Inspector panel when a solve starts (default on). Turn off if a starting solve stealing focus bothers you."
"default": false,
"description": "Automatically reveal the Run Inspector panel when a solve starts (default off, so a starting solve never steals focus). Leave off to open it on demand — the status-bar item or the \"Amicode: Open Run Inspector\" command. Turn on to have a starting solve reveal the panel automatically."
},
"amicode.opencodeBinary": {
"type": "string",
Expand Down
8 changes: 4 additions & 4 deletions packages/extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ServerManager } from "./server_manager";
import { fetchProviderSignal } from "./llm_creds.mjs";
import { resolveOpencodeBinary, OpencodeMissingError } from "./opencode_binary";
import { ChatPanel } from "./chat_panel";
import { registerRunInspector } from "./run_inspector";
import { registerRunInspector, revealInspector } from "./run_inspector";
import { registerCatalogCard } from "./catalog_card_shell";
import { registerTrees } from "./trees";
import { StatusBarManager } from "./status_bar";
Expand Down Expand Up @@ -316,7 +316,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
ChatPanel.openOrReveal(ctx, readyUrl);
}),
vscode.commands.registerCommand("amicode.openInspector", async () => {
await vscode.commands.executeCommand("amicode.runInspector.focus");
await revealInspector();
}),
// Run picker (pre-UX4 utility): switch the inspector between tracked runs.
// Picking pins the selection (a background solve won't steal the view);
Expand Down Expand Up @@ -358,7 +358,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
if (!pick) return;
if (pick.follow) runsManager?.resumeAutoFollow();
else if (pick.runId) runsManager?.selectRun(pick.runId);
await vscode.commands.executeCommand("amicode.runInspector.focus");
await revealInspector();
}),
vscode.commands.registerCommand("amicode.stopRun", async () => {
const dir = runsManager?.getActiveRunDir();
Expand Down Expand Up @@ -503,7 +503,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
runsManager?.pokeDiscovery();
runsManager?.selectRun(path.basename(runDir));
runsChannel.appendLine(`[demo] replayed → ${runDir}`);
await vscode.commands.executeCommand("amicode.runInspector.focus");
await revealInspector();
// Save-to-catalog prompt (#47): the watcher suppresses the promote
// prompt for runs already finished at switch (anti-re-pop), so the
// explicit replay owns its own prompt → the catalog card.
Expand Down
20 changes: 18 additions & 2 deletions packages/extension/src/run_inspector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class InspectorView implements vscode.WebviewViewProvider {
// Buffered in the pane regardless (shows when the user opens the panel);
// only steal focus when the auto-open setting is enabled (his UX gate).
if (autoOpenEnabled()) {
vscode.commands.executeCommand("amicode.runInspector.focus").then(undefined, () => undefined);
void revealInspector();
}
return;
}
Expand Down Expand Up @@ -226,7 +226,7 @@ class InspectorView implements vscode.WebviewViewProvider {
// default so a starting solve never steals focus; the status-bar item and
// the explicit open command (which bypasses reveal) remain available.
if (!autoOpenEnabled()) return;
vscode.commands.executeCommand("amicode.runInspector.focus").then(undefined, () => undefined);
void revealInspector();
}

// -------- internal --------
Expand Down Expand Up @@ -279,6 +279,22 @@ export function autoOpenEnabled(): boolean {
return vscode.workspace.getConfiguration("amicode").get<boolean>("inspector.autoOpen", false);
}

/** Context key gating the Run Inspector view (package.json `when`). It starts
* false on every window load and is NOT persisted, so VS Code never restores
* the panel on its own — the view only materializes once a reveal path flips
* it. That is what makes the inspector strictly button-press-only. */
export const INSPECTOR_CONTEXT_KEY = "amicode.inspectorRevealed";

/** The one way the Run Inspector is ever shown: flip the gate context key on
* (so the gated view is allowed to appear), then focus it. Every reveal path —
* the open command, the run picker, demo replay, and the opted-in auto-reveal —
* funnels through here, so the panel is only ever shown deliberately and never
* by VS Code's own view-state restoration. */
export async function revealInspector(): Promise<void> {
await vscode.commands.executeCommand("setContext", INSPECTOR_CONTEXT_KEY, true);
await vscode.commands.executeCommand("amicode.runInspector.focus");
}

function newNonce(): string {
let s = "";
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Expand Down
Loading