diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..26f17cc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,108 @@ +# Changelog + +All notable changes to this project are documented in this file. + +The format follows Keep a Changelog. Entries here describe repository changes +under review and do not claim a published extension, marketplace package, tag, +release, or stable API/ABI. + +## [Unreleased] + +The 2026-05-07 v002.1 PR ramp is grouped below. Late-day additions after +the initial changelog pass are appended after the first #124-#129 stack. + +### Status Surface + +- Added local read-only KV260 status readers, example JSON fixtures, CLI output, + documentation, and a VS Code prototype panel for launcher NPU status and lab + trace manifest data. [#124](https://github.com/pccxai/systemverilog-ide/pull/124) + +### UI Theme + +- Integrated copied pccx aperture logo assets, a prototype extension icon, the + pccx SystemVerilog Light color theme, and a copied-asset notice. [#125](https://github.com/pccxai/systemverilog-ide/pull/125) + +### Preflight Binding + +- Extended the read-only launcher status data with serial preflight snapshot + fields and surfaced tty, kernel, XRT, and timestamp values with missing-data + defaults. [#126](https://github.com/pccxai/systemverilog-ide/pull/126) + +### Polish + +- Rendered readiness details in a no-script VS Code webview with status pills, + evidence-path details, and maintainer empty states while retaining the + output-channel fallback. [#127](https://github.com/pccxai/systemverilog-ide/pull/127) + +### Palette + +- Added v002.1 command-palette navigation for the status panel, runbook, project + board, and trace help through the read-only panel or VS Code external URL + opening. [#128](https://github.com/pccxai/systemverilog-ide/pull/128) + +### Docs + +- Added the v002.1 readiness panel developer guide covering local enablement, + launcher-side data environment names, panel pill semantics, feedback routing, + and command-palette entries. [#129](https://github.com/pccxai/systemverilog-ide/pull/129) + +### Preflight Summary + +- Added a read-only board preflight summary card that parses bounded local + transcript fields, exposes a configurable transcript path, and keeps a + graceful empty state when no transcript is captured. [#130](https://github.com/pccxai/systemverilog-ide/pull/130) + +### Theme Variant + +- Added the pccx SystemVerilog Dark theme beside the light theme, including + manifest wiring, README listing, and JSON theme validation coverage. [#132](https://github.com/pccxai/systemverilog-ide/pull/132) + +### Settings + +- Added a checked settings schema for panel data sources, refresh interval, and + log level, mirrored the schema into the VS Code prototype contributions, and + normalized the settings at runtime. [#133](https://github.com/pccxai/systemverilog-ide/pull/133) + +### Keymap + +- Added default shortcuts for the read-only v002.1 PCCX commands and locked the + command-to-key mapping in the VS Code prototype manifest test. [#134](https://github.com/pccxai/systemverilog-ide/pull/134) + +### Developer Environment + +- Added a development Dockerfile for Python, Node, open HDL tools, OSS CAD + Suite, XRT utilities, Xilinx bootgen, OpenOCD, and openFPGALoader. [#135](https://github.com/pccxai/systemverilog-ide/pull/135) + +### Settings Docs + +- Added a dedicated VS Code prototype settings reference, linked it from the + prototype README, and covered schema-to-doc alignment in tests. [#136](https://github.com/pccxai/systemverilog-ide/pull/136) + +### Examples + +- Added a text-only first-use guide covering command palette, Problems and + Output panels, status-bar expectations, and the no-screenshot evidence + boundary. [#137](https://github.com/pccxai/systemverilog-ide/pull/137) + +### Quickstart + +- Added a five-step SV-IDE quickstart for install, panel, preflight, status, and + JSON export, with links from the root README and VS Code prototype README. [#138](https://github.com/pccxai/systemverilog-ide/pull/138) + +### Test Taxonomy + +- Added a T0-T7 test taxonomy for the Python CLI, checked examples, VS Code + prototype, boundary guards, and manual review evidence. [#139](https://github.com/pccxai/systemverilog-ide/pull/139) + +### Theme Docs + +- Added theme consistency rules for paired light and dark themes, including + structural parity, color keys, token buckets, and shared semantic roles. [#140](https://github.com/pccxai/systemverilog-ide/pull/140) + +### Guardrails + +- This changelog summarizes the #124-#130 and #132-#140 PR stack only; it does + not add or claim launcher execution, pccx-lab execution, serial writes, SSH, + board commands, provider calls, telemetry, uploads, write-back, packaging, + tags, or release flow. +- This changelog makes no marketplace flow claim and no stable API/ABI claim. diff --git a/docs/v002.1-readiness-panel-guide.md b/docs/v002.1-readiness-panel-guide.md new file mode 100644 index 0000000..06f45b5 --- /dev/null +++ b/docs/v002.1-readiness-panel-guide.md @@ -0,0 +1,133 @@ +# v002.1 Readiness Panel Developer Guide + +This guide is for maintainers wiring or reviewing the local read-only KV260 +readiness panel in the VS Code prototype. The panel is a status surface over +existing JSON inputs. It does not probe the board, open serial ports, execute +launcher or lab commands, run inference, package the extension, publish builds, +or write status back to any repository. + +## Scope + +The current panel stack is split across the v002.1 branches: + +- `pccxai/systemverilog-ide#124` adds the local `Kv260StatusPanel`, the + `pccxSystemVerilog.showKv260StatusPanel` command, and the + `sv-ide kv260-status` / `pccx-ide kv260-status` CLI text and JSON surface. +- `pccxai/systemverilog-ide#126` extends the launcher status reader with the + serial preflight snapshot fields provided by the launcher side. +- `pccxai/systemverilog-ide#127` renders the no-script VS Code webview: + aperture mark, metadata, color status pills, empty states, and collapsible + evidence-path details. +- `pccxai/systemverilog-ide#128` adds the v002.1 command-palette entries for + the panel, runbook link, project board link, and trace inspect help. + +## Enablement + +Use the local VS Code prototype scaffold under `editors/vscode-prototype`. +Load it in an Extension Development Host from this checkout, then open the +Command Palette and run either panel command: + +- `PCCX SystemVerilog: Show KV260 Status Panel (Experimental)` +- `PCCX: Show KV260 Status Panel` + +For non-UI review, run the local CLI status surface from the repository root: + +```bash +PYTHONPATH=src python3 -m pccx_ide_cli kv260-status --format text +PYTHONPATH=src python3 -m pccx_ide_cli kv260-status --format json +``` + +By default the CLI reads the tiny fixtures in +`docs/examples/kv260-status/`. Maintainers can pass local JSON files with +`--launcher-status` and `--trace-manifest` when reviewing a handoff. Keep +those files local unless the values have already been scrubbed for review. + +## Live Data Inputs + +The IDE panel does not read serial credentials or environment values. Live +board evidence enters the panel only after the owning launcher code writes a +launcher status JSON object with a `serial_probe` snapshot. + +Launcher-side serial preflight, from `pccxai/pccx-llm-launcher#72`, reads these +environment variable names: + +- `KVFPGA_TTY`: preferred KV260 serial tty path. If absent, the launcher may + attempt its own tty detection. +- `KVFPGA_USER`: serial login username used by the launcher preflight. +- `KVFPGA_PASSWORD`: serial login password used by the launcher preflight. +- `KVFPGA_HOST`: intentionally ignored by the launcher serial backend for this + tty path. + +The IDE-visible fields are the resulting JSON fields, not the environment +values: `launcher.serial_probe.status`, `tty_port`, `login_ok`, +`kernel_uname`, `xrt_present`, and `last_preflight_at`. Missing, blocked, or +not-run launcher input must stay visible as pending or failed panel state; the +IDE must not compensate by probing hardware itself. + +The trace side comes from the pccx-lab trace manifest contract in +`pccxai/pccx-lab#160`. The panel currently displays manifest metadata such as +schema version, bitstream UUID, AXI base, ISA version, frame count, source +kind, and runbook reference. + +## Pill Semantics + +Each checklist row maps to a fixed status pill: + +- `PASS`: the required value is present and true for that row. +- `PENDING`: launcher serial preflight has not run or no launcher status input + is configured. +- `FAIL`: launcher serial preflight ran but the row is missing, false, or + blocked. + +The current checklist rows are: + +- `serial tty port`: evidence path `launcher.serial_probe.tty_port` +- `serial login`: evidence path `launcher.serial_probe.login_ok` +- `XRT present`: evidence path `launcher.serial_probe.xrt_present` +- `serial preflight timestamp`: evidence path + `launcher.serial_probe.last_preflight_at` + +Treat a `PENDING` or `FAIL` row as a launch-path gate. The panel reports the +state; it does not decide that a hardware run is allowed. + +## Command Palette Entries + +PR #128 contributes these command IDs and titles: + +| Command ID | Title | Behavior | +| --- | --- | --- | +| `pccxSystemVerilog.showKv260StatusPanel` | `PCCX SystemVerilog: Show KV260 Status Panel (Experimental)` | Opens the read-only KV260 status panel. | +| `pccxSystemVerilog.v0021.showKv260StatusPanel` | `PCCX: Show KV260 Status Panel` | Opens the same read-only panel through the v002.1 command namespace. | +| `pccxSystemVerilog.v0021.openRunbook` | `PCCX: Open v002.1 Runbook` | Opens the v002.1 KV260 runbook URL through VS Code external navigation. | +| `pccxSystemVerilog.v0021.openProjectBoard` | `PCCX: Open Project Board` | Opens the PCCX project board URL through VS Code external navigation. | +| `pccxSystemVerilog.v0021.showTraceInspectHelp` | `PCCX: Show Trace Inspect Help` | Opens the pccx-lab trace pipeline doc URL through VS Code external navigation. | + +The three URL commands are navigation-only. They must not call GitHub APIs, +inspect project data, execute lab commands, or infer trace status locally. + +## Feedback Routing + +File panel and command-palette feedback in +`https://github.com/pccxai/systemverilog-ide/issues`. Include the command ID, +which JSON input path was used, the pill state, and the evidence path shown by +the panel. Do not include passwords, tokens, private tty paths, private home +paths, or raw board logs unless they have been reviewed for disclosure. + +Route launcher serial preflight issues to +`https://github.com/pccxai/pccx-llm-launcher/issues`, especially anything about +tty discovery, login, XRT probing, or the `serial_probe` JSON shape. + +Route trace manifest and `trace inspect` issues to +`https://github.com/pccxai/pccx-lab/issues`. + +## Review Guardrails + +- Keep the panel read-only and data-boundary-first. +- Do not add serial, SSH, shell, board-command, launcher-command, or lab-command + execution to the panel path. +- Do not add telemetry, upload, write-back, packaging, release, or tag flows. +- Do not print environment values in docs, tests, logs, PR bodies, or issues. +- Do not present `PASS` rows as proof of runtime inference, post-route signoff, + or hardware throughput. +- Keep new v002.1 commands explicit and command-palette discoverable; avoid + background polling, file watchers, and implicit workspace scans. diff --git a/editors/vscode-prototype/package.json b/editors/vscode-prototype/package.json index 8d4d713..ea7d6c9 100644 --- a/editors/vscode-prototype/package.json +++ b/editors/vscode-prototype/package.json @@ -35,7 +35,11 @@ "onCommand:pccxSystemVerilog.showContextBundleAudit", "onCommand:pccxSystemVerilog.showPccxLabBackendStatus", "onCommand:pccxSystemVerilog.showDiagnosticsHandoffSummary", - "onCommand:pccxSystemVerilog.showKv260StatusPanel" + "onCommand:pccxSystemVerilog.showKv260StatusPanel", + "onCommand:pccxSystemVerilog.v0021.showKv260StatusPanel", + "onCommand:pccxSystemVerilog.v0021.openRunbook", + "onCommand:pccxSystemVerilog.v0021.openProjectBoard", + "onCommand:pccxSystemVerilog.v0021.showTraceInspectHelp" ], "contributes": { "commands": [ @@ -130,6 +134,44 @@ { "command": "pccxSystemVerilog.showKv260StatusPanel", "title": "PCCX SystemVerilog: Show KV260 Status Panel (Experimental)" + }, + { + "command": "pccxSystemVerilog.v0021.showKv260StatusPanel", + "title": "PCCX: Show KV260 Status Panel" + }, + { + "command": "pccxSystemVerilog.v0021.openRunbook", + "title": "PCCX: Open v002.1 Runbook" + }, + { + "command": "pccxSystemVerilog.v0021.openProjectBoard", + "title": "PCCX: Open Project Board" + }, + { + "command": "pccxSystemVerilog.v0021.showTraceInspectHelp", + "title": "PCCX: Show Trace Inspect Help" + } + ], + "keybindings": [ + { + "command": "pccxSystemVerilog.v0021.showKv260StatusPanel", + "key": "ctrl+alt+k", + "mac": "cmd+alt+k" + }, + { + "command": "pccxSystemVerilog.v0021.openRunbook", + "key": "ctrl+alt+r", + "mac": "cmd+alt+r" + }, + { + "command": "pccxSystemVerilog.v0021.openProjectBoard", + "key": "ctrl+alt+p", + "mac": "cmd+alt+p" + }, + { + "command": "pccxSystemVerilog.v0021.showTraceInspectHelp", + "key": "ctrl+alt+i", + "mac": "cmd+alt+i" } ], "configuration": { diff --git a/editors/vscode-prototype/src/config.mjs b/editors/vscode-prototype/src/config.mjs index 0f0ae2c..7f50c2b 100644 --- a/editors/vscode-prototype/src/config.mjs +++ b/editors/vscode-prototype/src/config.mjs @@ -60,12 +60,20 @@ export const KV260_STATUS_COMMAND_IDS = Object.freeze([ "pccxSystemVerilog.showKv260StatusPanel", ]); +export const V0021_NAVIGATION_COMMAND_IDS = Object.freeze([ + "pccxSystemVerilog.v0021.showKv260StatusPanel", + "pccxSystemVerilog.v0021.openRunbook", + "pccxSystemVerilog.v0021.openProjectBoard", + "pccxSystemVerilog.v0021.showTraceInspectHelp", +]); + export const COMMAND_IDS = Object.freeze([ ...FACADE_COMMAND_IDS, ...WORKFLOW_COMMAND_IDS, ...PCCX_LAB_COMMAND_IDS, ...DIAGNOSTICS_HANDOFF_COMMAND_IDS, ...KV260_STATUS_COMMAND_IDS, + ...V0021_NAVIGATION_COMMAND_IDS, ]); export const MODES = Object.freeze(["checkedExample", "liveWorkspace"]); diff --git a/editors/vscode-prototype/src/extension.mjs b/editors/vscode-prototype/src/extension.mjs index 7190611..9f51767 100644 --- a/editors/vscode-prototype/src/extension.mjs +++ b/editors/vscode-prototype/src/extension.mjs @@ -120,6 +120,20 @@ export const SHOW_DIAGNOSTICS_HANDOFF_SUMMARY_COMMAND = "pccxSystemVerilog.showDiagnosticsHandoffSummary"; export const SHOW_KV260_STATUS_PANEL_COMMAND = "pccxSystemVerilog.showKv260StatusPanel"; +export const V0021_SHOW_KV260_STATUS_PANEL_COMMAND = + "pccxSystemVerilog.v0021.showKv260StatusPanel"; +export const OPEN_V0021_RUNBOOK_COMMAND = + "pccxSystemVerilog.v0021.openRunbook"; +export const OPEN_PROJECT_BOARD_COMMAND = + "pccxSystemVerilog.v0021.openProjectBoard"; +export const SHOW_TRACE_INSPECT_HELP_COMMAND = + "pccxSystemVerilog.v0021.showTraceInspectHelp"; +export const V0021_RUNBOOK_URL = + "https://github.com/pccxai/pccx-FPGA-NPU-LLM-kv260/blob/build/v002-kv260-bitstream-runbook/docs/runbooks/v002.1-bitstream-build.md"; +export const PCCX_PROJECT_BOARD_URL = + "https://github.com/orgs/pccxai/projects/1"; +export const TRACE_INSPECT_HELP_URL = + "https://github.com/pccxai/pccx-lab/blob/docs/trace-pipeline-overview/docs/trace-pipeline.md"; const NAVIGATION_LOCATION_COMMAND_IDS = Object.freeze([ CHECKED_EXAMPLE_NAVIGATION_COMMAND, @@ -127,6 +141,21 @@ const NAVIGATION_LOCATION_COMMAND_IDS = Object.freeze([ RUN_LIVE_NAVIGATION_COMMAND, ]); +const V0021_EXTERNAL_NAVIGATION_TARGETS = Object.freeze({ + [OPEN_V0021_RUNBOOK_COMMAND]: Object.freeze({ + label: "v002.1 runbook", + url: V0021_RUNBOOK_URL, + }), + [OPEN_PROJECT_BOARD_COMMAND]: Object.freeze({ + label: "project board", + url: PCCX_PROJECT_BOARD_URL, + }), + [SHOW_TRACE_INSPECT_HELP_COMMAND]: Object.freeze({ + label: "trace inspect help", + url: TRACE_INSPECT_HELP_URL, + }), +}); + export { COMMAND_IDS, FACADE_COMMAND_IDS, @@ -438,6 +467,9 @@ function appendCommandOutput(outputChannel, commandId, result) { if (result.kind === "kv260-status-panel") { outputChannel.appendLine(formatKv260StatusPanel(result.panel)); } + if (result.kind === "v0021-read-only-navigation") { + outputChannel.appendLine(JSON.stringify(result.target, null, 2)); + } if (result.status?.kind === "pccx-lab-backend-status") { outputChannel.appendLine(JSON.stringify(result.status, null, 2)); } @@ -473,6 +505,61 @@ function showKv260StatusWebview(vscodeApi, panel) { return webviewPanel; } +async function openExternalUrl(vscodeApi, url) { + const openExternal = vscodeApi?.env?.openExternal; + if (typeof openExternal !== "function") { + throw new Error("VS Code external URL navigation is unavailable"); + } + const uri = typeof vscodeApi?.Uri?.parse === "function" + ? vscodeApi.Uri.parse(url) + : url; + await openExternal.call(vscodeApi.env, uri); +} + +async function handleV0021ExternalNavigationCommand(commandId, vscodeApi) { + const target = V0021_EXTERNAL_NAVIGATION_TARGETS[commandId]; + if (!target) { + throw new Error(`unknown v002.1 navigation command: ${commandId}`); + } + await openExternalUrl(vscodeApi, target.url); + const result = { + ok: true, + commandId, + kind: "v0021-read-only-navigation", + target, + safety: { + shellExecution: false, + allowlistChange: false, + boardApiAccess: false, + marketplaceFlow: false, + }, + }; + vscodeApi?.window?.showInformationMessage?.( + `Opened ${target.label}.`, + result, + ); + return result; +} + +function createKv260StatusPanelResult(commandId, vscodeApi, runtime = {}) { + const panel = createKv260StatusPanel(runtime.kv260StatusInputs); + const result = { + ok: true, + commandId, + kind: "kv260-status-panel", + panel, + }; + const webviewPanel = showKv260StatusWebview(vscodeApi, panel); + if (webviewPanel) { + result.presentation = "webview"; + } + vscodeApi?.window?.showInformationMessage?.( + `KV260 status surface: ${panel.lab.frameCount} trace frame(s).`, + result, + ); + return result; +} + function facadeRunnerFromRuntime(runtime = {}) { return async (facadeArgs, env = {}) => { const invocation = { @@ -1136,24 +1223,25 @@ export function createCommandHandler(commandId, vscodeApi, runtime = {}) { return result; } - if (commandId === SHOW_KV260_STATUS_PANEL_COMMAND) { + if ( + commandId === SHOW_KV260_STATUS_PANEL_COMMAND || + commandId === V0021_SHOW_KV260_STATUS_PANEL_COMMAND + ) { let result; try { - const panel = createKv260StatusPanel(runtime.kv260StatusInputs); - result = { - ok: true, - commandId, - kind: "kv260-status-panel", - panel, - }; - const webviewPanel = showKv260StatusWebview(vscodeApi, panel); - if (webviewPanel) { - result.presentation = "webview"; - } - vscodeApi?.window?.showInformationMessage?.( - `KV260 status surface: ${panel.lab.frameCount} trace frame(s).`, - result, - ); + result = createKv260StatusPanelResult(commandId, vscodeApi, runtime); + } catch (error) { + result = { ok: false, commandId, error: error.message }; + vscodeApi?.window?.showWarningMessage?.(result.error, result); + } + appendCommandOutput(runtime.outputChannel, commandId, result); + return result; + } + + if (Object.hasOwn(V0021_EXTERNAL_NAVIGATION_TARGETS, commandId)) { + let result; + try { + result = await handleV0021ExternalNavigationCommand(commandId, vscodeApi); } catch (error) { result = { ok: false, commandId, error: error.message }; vscodeApi?.window?.showWarningMessage?.(result.error, result); diff --git a/editors/vscode-prototype/test/extension-entrypoint.test.mjs b/editors/vscode-prototype/test/extension-entrypoint.test.mjs index 29323e2..3002417 100644 --- a/editors/vscode-prototype/test/extension-entrypoint.test.mjs +++ b/editors/vscode-prototype/test/extension-entrypoint.test.mjs @@ -14,7 +14,11 @@ import { CHECKED_EXAMPLE_NAVIGATION_COMMAND, FACADE_COMMAND_IDS, LIVE_WORKSPACE_NAVIGATION_COMMAND, + OPEN_PROJECT_BOARD_COMMAND, + OPEN_V0021_RUNBOOK_COMMAND, + PCCX_PROJECT_BOARD_URL, PCCX_LAB_BACKEND_STATUS_COMMAND, + SHOW_TRACE_INSPECT_HELP_COMMAND, SHOW_CONTEXT_BUNDLE_AUDIT_COMMAND, SHOW_DIAGNOSTICS_HANDOFF_SUMMARY_COMMAND, SHOW_KV260_STATUS_PANEL_COMMAND, @@ -22,7 +26,10 @@ import { SHOW_PATCH_PROPOSAL_PREVIEW_COMMAND, SHOW_RECENT_VALIDATION_RESULTS_COMMAND, SHOW_VALIDATION_CACHE_STATUS_COMMAND, + TRACE_INSPECT_HELP_URL, VALIDATION_PROPOSAL_COMMAND, + V0021_RUNBOOK_URL, + V0021_SHOW_KV260_STATUS_PANEL_COMMAND, activate, buildFacadeArgsForCommand, buildFacadeInvocationForCommand, @@ -1592,6 +1599,64 @@ async function testKv260StatusPanelCommandRendersExistingWebviewOnly() { assert.match(webviewPanel.webview.html, /
/); } +async function testV0021Kv260StatusPanelAliasUsesExistingPanel() { + const handler = createCommandHandler(V0021_SHOW_KV260_STATUS_PANEL_COMMAND, null, {}); + + const result = await handler(); + + assert.equal(result.ok, true); + assert.equal(result.commandId, V0021_SHOW_KV260_STATUS_PANEL_COMMAND); + assert.equal(result.kind, "kv260-status-panel"); + assert.equal(result.panel.kind, "kv260-status-panel"); + assert.equal(result.panel.safety.launcherExecution, false); + assert.equal(result.panel.safety.pccxLabExecution, false); + assert.equal(result.panel.safety.shellExecution, false); + assert.equal(result.panel.safety.sshExecution, false); +} + +async function testV0021ExternalNavigationCommandsOpenUrlsOnly() { + const opened = []; + const vscodeApi = { + Uri: { + parse(url) { + return { url }; + }, + }, + env: { + async openExternal(uri) { + opened.push(uri.url); + }, + }, + window: { + showInformationMessage() {}, + }, + }; + + const commands = [ + [OPEN_V0021_RUNBOOK_COMMAND, V0021_RUNBOOK_URL], + [OPEN_PROJECT_BOARD_COMMAND, PCCX_PROJECT_BOARD_URL], + [SHOW_TRACE_INSPECT_HELP_COMMAND, TRACE_INSPECT_HELP_URL], + ]; + + for (const [commandId, expectedUrl] of commands) { + const handler = createCommandHandler(commandId, vscodeApi, {}); + const result = await handler(); + + assert.equal(result.ok, true); + assert.equal(result.commandId, commandId); + assert.equal(result.kind, "v0021-read-only-navigation"); + assert.equal(result.target.url, expectedUrl); + assert.deepEqual(result.safety, { + shellExecution: false, + allowlistChange: false, + boardApiAccess: false, + marketplaceFlow: false, + }); + } + + assert.deepEqual(opened, commands.map(([_commandId, url]) => url)); +} + testKnownFacadeArgs(); testUnknownCommandsRejected(); testCheckedExampleDiagnosticsCommandStaysExampleMode(); @@ -1622,5 +1687,7 @@ await testDiagnosticsHandoffSummaryCommandReturnsDataOnlySurface(); await testPccxLabBackendStatusCommandReturnsStatusOnly(); await testKv260StatusPanelCommandReturnsDataOnlySurface(); await testKv260StatusPanelCommandRendersExistingWebviewOnly(); +await testV0021Kv260StatusPanelAliasUsesExistingPanel(); +await testV0021ExternalNavigationCommandsOpenUrlsOnly(); console.log("vscode extension entrypoint tests ok"); diff --git a/editors/vscode-prototype/test/extension-manifest.test.mjs b/editors/vscode-prototype/test/extension-manifest.test.mjs index 6304074..e2743c2 100644 --- a/editors/vscode-prototype/test/extension-manifest.test.mjs +++ b/editors/vscode-prototype/test/extension-manifest.test.mjs @@ -32,6 +32,40 @@ const COMMAND_IDS = [ "pccxSystemVerilog.showPccxLabBackendStatus", "pccxSystemVerilog.showDiagnosticsHandoffSummary", "pccxSystemVerilog.showKv260StatusPanel", + "pccxSystemVerilog.v0021.showKv260StatusPanel", + "pccxSystemVerilog.v0021.openRunbook", + "pccxSystemVerilog.v0021.openProjectBoard", + "pccxSystemVerilog.v0021.showTraceInspectHelp", +]; + +const V0021_COMMAND_TITLES = new Map([ + ["pccxSystemVerilog.v0021.showKv260StatusPanel", "PCCX: Show KV260 Status Panel"], + ["pccxSystemVerilog.v0021.openRunbook", "PCCX: Open v002.1 Runbook"], + ["pccxSystemVerilog.v0021.openProjectBoard", "PCCX: Open Project Board"], + ["pccxSystemVerilog.v0021.showTraceInspectHelp", "PCCX: Show Trace Inspect Help"], +]); + +const V0021_KEYBINDINGS = [ + { + command: "pccxSystemVerilog.v0021.showKv260StatusPanel", + key: "ctrl+alt+k", + mac: "cmd+alt+k", + }, + { + command: "pccxSystemVerilog.v0021.openRunbook", + key: "ctrl+alt+r", + mac: "cmd+alt+r", + }, + { + command: "pccxSystemVerilog.v0021.openProjectBoard", + key: "ctrl+alt+p", + mac: "cmd+alt+p", + }, + { + command: "pccxSystemVerilog.v0021.showTraceInspectHelp", + key: "ctrl+alt+i", + mac: "cmd+alt+i", + }, ]; async function readText(path) { @@ -106,9 +140,28 @@ async function testCommandContributions() { `${commandId} missing activation event`, ); } + for (const [commandId, title] of V0021_COMMAND_TITLES) { + assert.equal( + manifest.contributes.commands.find((command) => command.command === commandId)?.title, + title, + ); + } assert.equal(contributedCommands.size, COMMAND_IDS.length); } +async function testV0021DefaultKeybindings() { + const manifest = await readPackageJson(); + const keybindings = manifest.contributes?.keybindings; + + assert.deepEqual(keybindings, V0021_KEYBINDINGS); + for (const keybinding of keybindings) { + assert.ok(COMMAND_IDS.includes(keybinding.command)); + assert.match(keybinding.key, /^ctrl\+alt\+[a-z]$/); + assert.match(keybinding.mac, /^cmd\+alt\+[a-z]$/); + assert.equal(Object.hasOwn(keybinding, "when"), false); + } +} + async function testDocsKeepExperimentalScope() { const readme = await readText(resolve(EXTENSION_ROOT, "README.md")); const contract = await readText(resolve(ROOT, "docs/EDITOR_BRIDGE_CONTRACT.md")); @@ -148,6 +201,7 @@ async function testDocsKeepExperimentalScope() { await testPackageManifestShape(); await testNoMarketplacePublishingShape(); await testCommandContributions(); +await testV0021DefaultKeybindings(); await testDocsKeepExperimentalScope(); console.log("vscode extension manifest tests ok");