Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
3636ee4
tdd and readme
ccapetz Jun 17, 2026
aa9d94a
Add MRD Viz scaffold
ccapetz Jun 18, 2026
6252280
Add MRD viewer webview mosaic MVP
ccapetz Jun 22, 2026
3de523a
phase 1, 2, 3
ccapetz Jun 23, 2026
a56c816
addressed minor TDD feedback to merge PR. open questions remaining on…
ccapetz Jun 23, 2026
8caf613
Merge pull request #71 from ismrmrd/add-mrd-viz-tdd
ccapetz Jun 23, 2026
d338e40
removed backend folder from PR
ccapetz Jun 23, 2026
25428e0
Merge branch 'carter-mrd-viz' into add-mrd-viz-scaffold
ccapetz Jun 23, 2026
4968abe
removed vsc-extension-quickstart.md
ccapetz Jun 24, 2026
febf911
backend logic linked to frontend webview UI
ccapetz Jun 24, 2026
7001076
Split mrd-viz ignore rules
ccapetz Jun 24, 2026
c9b127b
Merge pull request #72 from ismrmrd/add-mrd-viz-scaffold
ccapetz Jun 24, 2026
2dd6730
Add MRD Viz backend CLI
ccapetz Jun 26, 2026
a80e1a6
Potential fix for pull request finding
ccapetz Jun 29, 2026
bce24e7
friendlier/consistent CLI error message
ccapetz Jun 29, 2026
6eaf010
small formatting fix
ccapetz Jun 29, 2026
4edcfa3
dead code
ccapetz Jun 29, 2026
236bf55
avoid rendering thumbnails that will never be returned
ccapetz Jun 29, 2026
7405a72
Remove unused import from stage1.py
ccapetz Jun 29, 2026
d4eedc5
modified dev runbook to include linux bash commands
ccapetz Jun 29, 2026
c0f7e8b
Merge branch 'add-mrd-viz-backend-cli' of https://github.com/ismrmrd/…
ccapetz Jun 29, 2026
bfcd158
renamed stage1 -> main (updated downstream refs etc), implemented ear…
ccapetz Jun 30, 2026
f115a44
backend test suite
ccapetz Jul 1, 2026
1d5212f
added justfile and github action
ccapetz Jul 1, 2026
4e203bd
remove test mrd files
ccapetz Jul 1, 2026
00cf37d
added warnings for file classification reliability during partial rea…
ccapetz Jul 1, 2026
d4fd6d7
Merge pull request #75 from ismrmrd/add-mrd-viz-backend-cli
ccapetz Jul 1, 2026
ef2882c
Merge remote-tracking branch 'origin/carter-mrd-viz' into mrd-viz-web…
ccapetz Jul 1, 2026
94834e9
extension webview functionality
ccapetz Jul 1, 2026
5201935
clicking mrd files in explorer sidebar entry point.
ccapetz Jul 2, 2026
b9e6eac
Address PR #76 review feedback (C1-C6)
ccapetz Jul 6, 2026
27c75dc
Fix npm audit vulnerabilities in extension dev deps (item A)
ccapetz Jul 7, 2026
219a441
Address PR #76 round 2: wire viewer subscription up front; hoist cach…
ccapetz Jul 8, 2026
fab7811
Address PR #76 round 2: scheme/mrd validation, stderr on success, chi…
ccapetz Jul 8, 2026
1b1c91a
Make runImage consistent with runOpenFile: stderr + cancellation
ccapetz Jul 8, 2026
6647fd2
Merge pull request #76 from ismrmrd/mrd-viz-webview-mvp
ccapetz Jul 8, 2026
8bf2c18
Add VSIX packaging setup and local-install runbook
ccapetz Jul 8, 2026
5ea9a83
Drop duplicate extension LICENSE; rely on MIT field + root LICENSE
ccapetz Jul 9, 2026
0e5ca21
Make backend setup self-contained in packaging runbook
ccapetz Jul 9, 2026
b30a71c
Merge pull request #77 from ismrmrd/vsix-packaging
ccapetz Jul 9, 2026
532215a
Add lightweight MRD Viz dev container (Scenario B) + one-command setup
ccapetz Jul 9, 2026
d33b32d
Devcontainer: install Node from nodejs.org, support restricted-networ…
ccapetz Jul 10, 2026
c65a1f1
Docs: warn that mrdViz.pythonPath belongs in User settings, not Works…
ccapetz Jul 10, 2026
263f87a
az login typo
ccapetz Jul 10, 2026
9d336f9
Address PR #78 review: arch-aware Node/azcopy, safer just install, cl…
ccapetz Jul 10, 2026
fe32919
Address PR feedback: root just recipe for container setup, bundle LIC…
ccapetz Jul 13, 2026
a93b905
Merge pull request #78 from ismrmrd/mrd-viz-devcontainer
ccapetz Jul 13, 2026
f872d85
D1: robust backend discovery + guided setup; release workflow
ccapetz Jul 13, 2026
efa3c5e
D3 scaffold: PyInstaller standalone backend + platform VSIX matrix
ccapetz Jul 13, 2026
e299975
D3: one-dir build runs under Application Control without signing
ccapetz Jul 13, 2026
72fd869
ci: run release build matrix on mrd-viz PRs as a dry run (release ste…
ccapetz Jul 13, 2026
23651d1
mrd-viz: actionable backend-missing page with per-candidate diagnostics
ccapetz Jul 23, 2026
5ccc969
mrd-viz: address PR review feedback on backend discovery
ccapetz Jul 27, 2026
f2f75bb
mrd-viz: auto-provision the backend venv in the dev container postCreate
ccapetz Jul 27, 2026
74a6a8d
F10 Phase 3: split webviewHtml.ts state/util helpers into modules
ccapetz Jul 17, 2026
9ed3af0
F10 Phase 1+2: extract webview client JS/CSS into media/ with esbuild
ccapetz Jul 20, 2026
4ec070a
F10 Phase 4: full-window view plus zoom/pan for the selected image
ccapetz Jul 20, 2026
839a593
F10 Phase 5: step through image slices (mosaic-wide and per-tile)
ccapetz Jul 20, 2026
f8f23f5
mrd-viz: refine selected-image inspection UX
ccapetz Jul 20, 2026
dd6b80d
mrd-viz: add Images/Slices mosaic mode toggle for 3D volumes
ccapetz Jul 20, 2026
f144119
mrd-viz: fix Slices-mode mosaic selection to use a unique per-tile key
ccapetz Jul 23, 2026
f71549b
Merge pull request #81 from ismrmrd/webview-refactor-and-viewer-ux
ccapetz Jul 27, 2026
83712f6
Merge pull request #79 from ismrmrd/mrd-viz-backend-discovery
ccapetz Jul 27, 2026
7890d8d
mrd-viz: clean up failed backend venv and report step-tagged errors
ccapetz Jul 30, 2026
3eeb042
mrd-viz: split webview viewer.ts into focused media modules
ccapetz Jul 30, 2026
97bb257
small naming fix
ccapetz Jul 30, 2026
5087bbd
small wording fix
ccapetz Jul 30, 2026
afc1096
mrd-viz: address review - preserve notices on mosaic toggle, clear st…
ccapetz Jul 30, 2026
7a33124
Merge pull request #83 from ismrmrd/webview-media-module-split
ccapetz Jul 30, 2026
b55ec1d
mrd-viz: restore catch clause in removeIncompleteVenv
ccapetz Jul 30, 2026
7fa1fdc
mrd-viz CI: cap build timeout and retry PyInstaller build for flaky d…
ccapetz Jul 30, 2026
0af67c3
mrd-viz CI: drop flaky darwin-x64 (Intel macos-13) build leg
ccapetz Aug 3, 2026
3d8f4c4
mrd-viz: stop tracking generated webview bundle (media/viewer.js)
ccapetz Aug 3, 2026
b8f84df
Merge pull request #85 from ismrmrd/mrd-viz-gitignore-viewer-bundle
ccapetz Aug 3, 2026
d538d50
Merge pull request #84 from ismrmrd/mrd-viz-fix-darwin-x64-ci
ccapetz Aug 3, 2026
63c1889
mrd-viz: robust failed-venv cleanup + invalidate cache + tests
ccapetz Aug 4, 2026
882ff95
Merge pull request #82 from ismrmrd/failed-venv-cleanup-fix
ccapetz Aug 4, 2026
f34f807
docs(mrd-viz): add backend install-modes analysis and resolution impl…
ccapetz Aug 4, 2026
4875e1d
mrd-viz(resolver): deterministic two-tier backend resolution
ccapetz Aug 4, 2026
55902e0
mrd-viz(setup): persist selected/provisioned interpreter to backendPath
ccapetz Aug 4, 2026
058b5ac
mrd-viz(ui): tailor backend-missing page to override vs bundled failure
ccapetz Aug 4, 2026
94a9671
mrd-viz(devcontainer): point at the venv via machine-scoped backendPath
ccapetz Aug 4, 2026
0e958de
mrd-viz(test,docs): resolution-order tests; mark target architecture …
ccapetz Aug 4, 2026
c6d6d60
mrd-viz: address review - label override by actual setting, fix snipp…
ccapetz Aug 7, 2026
4eef535
mrd-viz: address backend-resolution review follow-ups
ccapetz Aug 7, 2026
fc2fb4d
mrd-viz: drop legacy mrdViz.pythonPath override support
ccapetz Aug 7, 2026
36f5f31
mrd-viz: auto-select internal-vs-public package index on restricted n…
ccapetz Aug 12, 2026
d23c2e1
mrd-viz: address PR #86 review comments
ccapetz Aug 12, 2026
d47f9ea
Merge pull request #86 from ismrmrd/mrd-viz-backend-resolution-core
ccapetz Aug 12, 2026
ed80951
mrd-viz: keep WIP internal docs untracked until ready for review
ccapetz Aug 12, 2026
6f49ef0
docs(mrd-viz): add Marketplace release TODO checklist
ccapetz Aug 13, 2026
3bc1e97
feat(mrd-viz): add 128x128 extension icon and wire into manifest
ccapetz Aug 13, 2026
13efe01
chore(mrd-viz): track extension icon assets (override *.png ignore)
ccapetz Aug 13, 2026
c846ef1
chore(mrd-viz): add extension LICENSE.txt and update release checklist
ccapetz Aug 13, 2026
8b24a0b
ci(mrd-viz): scaffold guarded Marketplace publish job
ccapetz Aug 14, 2026
6807e4a
docs(mrd-viz): document Marketplace publish job + handoff notes in re…
ccapetz Aug 14, 2026
0923965
Merge pull request #88 from ismrmrd/mrd-viz-release
ccapetz Aug 14, 2026
29c386b
ci(mrd-viz): target main for PR checks; pin vsce and gh-release action
ccapetz Aug 14, 2026
7ac9ffd
fix(mrd-viz): bound --slice axis and guard non-array thumbnails
ccapetz Aug 14, 2026
1de213f
mrd-viz: prepare researcher release
Copilot Aug 25, 2026
25c32a9
mrd-viz: scaffold D3 artifact verification
Copilot Aug 25, 2026
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
42 changes: 42 additions & 0 deletions .devcontainer/mrd-viz/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
// Lightweight, extension-specific dev container for MRD Viz (Scenario B).
// The other config, ".devcontainer/devcontainer.json" ("mrd"), is the full
// repo toolchain (conda + MATLAB + C++) and is a poor fit for just viewing
// .mrd files, so this pins Python 3.12 (matching the backend) and stays minimal.
"name": "MRD Viz extension",
"image": "mcr.microsoft.com/devcontainers/python:3.12-bookworm",
"features": {
"ghcr.io/devcontainers/features/azure-cli:1": {}
},
// postCreate installs Node.js (from nodejs.org), plus the `just` and `azcopy`
// CLIs. Node is installed here rather than via the devcontainer `node` feature
// because that feature pulls pnpm from the public npm registry at build time,
// which is blocked on some corporate networks. Project provisioning (backend +
// the MRD Viz extension) is a one-time `just container-setup` you run afterwards.
"postCreateCommand": "bash .devcontainer/mrd-viz/postCreate.sh",
// Ordered package-index candidates (Microsoft-internal mirror first, public
// registry as fallback). `.devcontainer/mrd-viz/select-pkg-index.sh` picks the
// first reachable one and exports PIP_INDEX_URL / npm_config_registry, so the
// internal feed lives here — not in a hidden dotfile — and external contributors
// fall back to the public registry automatically. Override either list, or set
// PIP_INDEX_URL / npm_config_registry directly, to force a specific feed.
"remoteEnv": {
"MRD_PIP_INDEX_URLS": "https://packagefeedproxy.microsoft.io/pypi/simple/ https://pypi.org/simple/",
"MRD_NPM_REGISTRIES": "https://packagefeedproxy.microsoft.io/npm/ https://registry.npmjs.org/"
},
"customizations": {
"vscode": {
"settings": {
// `just container-setup` creates this venv; pointing the extension at it
// explicitly (via the developer override) avoids the installed-VSIX discovery
// gap and the python/python3 PATH ambiguity. backendPath is machine-scoped, so
// this applies as a container remote setting and never leaks back to the host.
"mrdViz.backendPath": "/home/vscode/.venvs/mrd-viz/bin/python",
"python.defaultInterpreterPath": "/home/vscode/.venvs/mrd-viz/bin/python"
},
"extensions": [
"ms-python.python"
]
}
}
}
104 changes: 104 additions & 0 deletions .devcontainer/mrd-viz/postCreate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env bash
# postCreate for the MRD Viz dev container.
# Installs the generic CLI tools the workflow needs, then best-effort provisions
# the backend virtualenv so the container is turnkey for a first run. Building and
# installing the extension VSIX stays a one-time `just mrd-viz-container-setup`
# step (it needs the npm registry, which is what fails on restricted networks).
set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

# Resolve the container architecture so the Node and azcopy downloads match it.
arch="$(uname -m)"
case "$arch" in
x86_64) node_arch="x64"; azcopy_url="https://aka.ms/downloadazcopy-v10-linux"; azcopy_glob="azcopy_linux_amd64_*" ;;
aarch64|arm64) node_arch="arm64"; azcopy_url="https://aka.ms/downloadazcopy-v10-linux-arm64"; azcopy_glob="azcopy_linux_arm64_*" ;;
*) echo ">> Unsupported architecture: $arch" >&2; exit 1 ;;
esac

# Node.js (from nodejs.org, which is reachable even where the public npm registry
# is blocked). Installed here instead of the devcontainer `node` feature, which
# pulls pnpm from the public npm registry at build time. Node bundles npm.
if ! command -v node >/dev/null 2>&1; then
echo ">> Installing Node.js"
node_version="v24.18.0"
curl -fsSL "https://nodejs.org/dist/${node_version}/node-${node_version}-linux-${node_arch}.tar.xz" -o /tmp/node.tar.xz
sudo tar -xJf /tmp/node.tar.xz -C /usr/local --strip-components=1
rm -f /tmp/node.tar.xz
fi

# just: task runner used by `just container-setup`.
if ! command -v just >/dev/null 2>&1; then
echo ">> Installing just"
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh -o /tmp/just-install.sh
sudo bash /tmp/just-install.sh --to /usr/local/bin
rm -f /tmp/just-install.sh
fi

# azcopy: used to pull .mrd data from Azure storage.
if ! command -v azcopy >/dev/null 2>&1; then
echo ">> Installing azcopy"
curl -sSL "$azcopy_url" -o /tmp/azcopy.tar.gz
tar -xzf /tmp/azcopy.tar.gz -C /tmp
sudo cp /tmp/${azcopy_glob}/azcopy /usr/local/bin/azcopy
sudo chmod +x /usr/local/bin/azcopy
rm -rf /tmp/azcopy.tar.gz /tmp/${azcopy_glob}
fi

# Backend provisioning (best-effort, non-fatal). The dev container points
# mrdViz.backendPath at this venv, so create it and install the mrd_viz backend
# now for a turnkey first run. This only needs PyPI (mrd-python/numpy/pillow),
# which is typically reachable even where the npm registry is blocked; the guard
# keeps a failure from aborting container creation and falls back to the manual
# step in the banner below.
venv="$HOME/.venvs/mrd-viz"
backend_dir="$repo_root/mrd-viz/backend"
backend_ready=0
if [ -x "$venv/bin/python" ] && "$venv/bin/python" -m mrd_viz.cli --version >/dev/null 2>&1; then
backend_ready=1
elif [ -d "$backend_dir" ]; then
# Point pip at the first reachable index (internal mirror, else public PyPI).
# shellcheck source=./select-pkg-index.sh
source "$repo_root/.devcontainer/mrd-viz/select-pkg-index.sh"
echo ">> Provisioning MRD Viz backend virtualenv: $venv"
if python3 -m venv "$venv" \
&& "$venv/bin/python" -m pip install --upgrade pip \
&& "$venv/bin/python" -m pip install -e "$backend_dir"; then
backend_ready=1
else
echo ">> WARNING: automatic backend setup failed (often a blocked/restricted network)." >&2
rm -rf "$venv"
fi
fi

if [ "$backend_ready" -eq 1 ]; then
cat <<'EOF'

============================================================
MRD Viz dev container is ready. Backend is installed and
mrdViz.backendPath points at ~/.venvs/mrd-viz, so opening a
.mrd file should work out of the box.

If the MRD Viz extension itself is not installed yet, run:
just mrd-viz-container-setup
(builds + installs the extension VSIX; needs npm registry
access - see mrd-viz/docs/DEVCONTAINER.md for restricted
networks).
============================================================
EOF
else
cat <<'EOF'

============================================================
MRD Viz dev container is ready, but automatic backend setup
did not complete (often a blocked/restricted network).

Finish setup by running:
just mrd-viz-container-setup

That creates the backend virtualenv, installs mrd_viz, and
builds + installs the MRD Viz extension in this window.
See mrd-viz/docs/DEVCONTAINER.md for restricted-network tips.
============================================================
EOF
fi
59 changes: 59 additions & 0 deletions .devcontainer/mrd-viz/select-pkg-index.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# shellcheck shell=bash
# Pick the first reachable package index/registry from an ordered, space-separated
# candidate list and export the variables pip and npm read natively
# (PIP_INDEX_URL, npm_config_registry). Source this before running pip/npm.
#
# Candidate ladder (same idea as the backend resolver): the Microsoft-internal
# mirror is tried first, the public registry second. Microsoft-internal devs on a
# restricted network get the mirror; external devs fall back to the public
# registry automatically. The lists come from devcontainer.json (remoteEnv):
# MRD_PIP_INDEX_URLS e.g. "https://internal/pypi/simple/ https://pypi.org/simple/"
# MRD_NPM_REGISTRIES e.g. "https://internal/npm/ https://registry.npmjs.org/"
# When unset (running outside the dev container), they default to public only.
#
# Override the final choice by exporting PIP_INDEX_URL / npm_config_registry
# yourself before sourcing; an explicit value is always respected.

: "${MRD_PIP_INDEX_URLS:=https://pypi.org/simple/}"
: "${MRD_NPM_REGISTRIES:=https://registry.npmjs.org/}"

# Echo the first URL in $1 (space-separated) whose host completes an HTTPS request
# within a short timeout. Any HTTP response (even 404) counts as reachable; only a
# TLS handshake / connection failure — the restricted-network symptom — is a miss.
_mrd_first_reachable() {
local url
for url in $1; do
if curl -sS --max-time 6 -o /dev/null -I "$url" >/dev/null 2>&1; then
printf '%s' "$url"
return 0
fi
done
return 1
}

# pip
if [ -n "${PIP_INDEX_URL:-}" ]; then
echo ">> Using PyPI index (from PIP_INDEX_URL): $PIP_INDEX_URL"
elif _pip_url="$(_mrd_first_reachable "$MRD_PIP_INDEX_URLS")"; then
export PIP_INDEX_URL="$_pip_url"
echo ">> Using PyPI index: $PIP_INDEX_URL"
else
echo ">> WARNING: no reachable PyPI index among: $MRD_PIP_INDEX_URLS" >&2
echo ">> If you are on a restricted/corporate network, run this and retry:" >&2
echo ">> export PIP_INDEX_URL=\"${MRD_PIP_INDEX_URLS%% *}\"" >&2
fi

# npm
if [ -n "${npm_config_registry:-}" ]; then
echo ">> Using npm registry (from npm_config_registry): $npm_config_registry"
elif _npm_url="$(_mrd_first_reachable "$MRD_NPM_REGISTRIES")"; then
export npm_config_registry="$_npm_url"
echo ">> Using npm registry: $npm_config_registry"
else
echo ">> WARNING: no reachable npm registry among: $MRD_NPM_REGISTRIES" >&2
echo ">> If you are on a restricted/corporate network, run this and retry:" >&2
echo ">> export npm_config_registry=\"${MRD_NPM_REGISTRIES%% *}\"" >&2
fi

unset -f _mrd_first_reachable
unset _pip_url _npm_url
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Shell scripts and justfiles run inside Linux dev containers; keep them LF
# so bash/just don't choke on CR characters even when edited on Windows.
*.sh text eol=lf
justfile text eol=lf
42 changes: 42 additions & 0 deletions .github/workflows/mrd_viz.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: MRD Viz

on:
pull_request:
branches: [main]
paths:
- "mrd-viz/**"
- ".github/workflows/mrd_viz.yml"
push:
branches: [main]
paths:
- "mrd-viz/**"
- ".github/workflows/mrd_viz.yml"
workflow_dispatch:

jobs:
ci:
name: Backend and Extension Checks
runs-on: ubuntu-24.04

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"

- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: "22"
cache: npm
cache-dependency-path: mrd-viz/extension/mrd-viz/package-lock.json

- name: Set up just
uses: extractions/setup-just@v4

- name: Run MRD Viz CI
working-directory: mrd-viz
run: just ci
Loading