8.3 KiB
AGENTS.md
This file provides guidance to AI coding agents (Claude, Codex, and other LLM tools) when working with code in this repository.
Project Overview
This is OHIF v3 (Open Health Imaging Foundation) - a medical imaging viewer. It's an extensible web imaging platform.
Development Commands
Main Development
# Start development server for all packages
yarn dev
Building
# Build all packages for production
yarn build
# Build specific packages
cd platform/app && yarn build # Main viewer app
Architecture Overview
Monorepo Structure
platform/- Core OHIF infrastructureapp/- Main viewer application (@ohif/viewer)core/- Core services and utilitiesui-next/- Modern UI component library
extensions/- Modular functionality pluginsmodes/- Application workflow configurations
Key Extension Architecture
Extension System: Each extension exports modules (viewports, tools, panels, commands) that the app dynamically loads. Extensions are self-contained with their own webpack builds.
Core Extensions:
cornerstone/- Medical image rendering enginecornerstone-dicom-pmp/- DICOM PMP supportcornerstone-dicom-seg/- DICOM Segmentation supportcornerstone-dicom-sr/- DICOM SR supportdicom-pdf/- DICOM PDF supportdicom-video/- DICOM Video supportmeasurement-tracking/- Measurement tracking supportdefault/- Standard OHIF functionality
Service-Oriented Design (PUB-SUB)
The app uses a Services Manager pattern with these core services:
- Display Set Service: Manages image series organization
- Measurement Service: Handles annotations and measurements
- Hanging Protocol Service: Controls image layout and display rules
- UI Service: Manages panels, modals, and notifications
- Segmentation Service: AI/ML powered image segmentation, loading segmentations, etc.
- Viewport Grid Service: Manages viewport layout and display rules
- Viewport Display Set History Service: Manages viewport display set history
- Viewport Dialog Service: Manages viewport dialogs
- Notification Service: Manages notifications
- Modal Service: Manages modals
- Dialog Service: Manages dialogs, more general not just viewport dialogs
- Customization Service: Manages customization of the app
- Toolbar Service: Manages the toolbar, viewport action corners, tool states
- User Authentication Service: Manages user authentication, but used only for injecting tokens in dicomweb requests in our context
- Panel Service: Manages side panels
- Cornerstone Viewport Service: Manages the cornerstone viewport, rendering engines, presentation states, more tightly coupled to cornerstone than the other services
- Tool Group Service: Manages tool groups, creating and managing tool groups, etc.
- Sync Group Service: Manages sync groups, syncing zooming, panning, scrolling, etc.
- Cornerstone Cache Service: Manages the cornerstone cache, caching images, etc.
Most of the services utilize a pub sub architecture and extend the pub sub service interace at pubSubServiceInterface.ts
Commands Manager
The Commands Manager tracks named commands (or functions) that are scoped to a context. When we attempt to run a command with a given name, we look for it in our active contexts, in the order specified. If found, we run the command, passing in any application or call specific data specified in the command's definition.
You can call commandsManager.runCommand to run a command.
Extension Manager
Aggregates and exposes extension modules throughout the OHIF application, manages data sources, and provides a centralized registry for accessing extension functionality.
Build System
Yarn Workspaces: Optimized monorepo builds with dependency caching
Webpack 5: Module federation for dynamic extension loading
Plugin Import System: Extensions auto-register via writePluginImportsFile.js
Key Technologies
- React 18 + TypeScript: UI framework
- Cornerstone.js: Medical image rendering
- DICOM: Medical imaging standard support
- ONNX Runtime: AI model inference (SAM segmentation models)
- Zustand: State management
- TailwindCSS: Styling system
Development Patterns
Adding New Tools
- Create tool class in
extensions/cornerstone/src/tools/ - Register in tool module's
toolNames.ts - Add to toolbar via
getToolbarModule.tsx - Add measurement mapping if needed in
measurementServiceMappings/
Creating Extensions
Extensions must export:
id.js- Unique extension identifierindex.tsx- Extension registration- Module functions (
getToolbarModule,getViewportModule, etc.)
Viewport Customization
Custom viewports extend base Cornerstone viewport:
- Override render methods for custom overlays
- Implement measurement tracking
- Add viewport-specific tools and interactions
Service Integration
Register services in extension's servicesManager.registerService and access via:
const { MeasurementService } = servicesManager.services;
Creating stores
To create a store, you can make one in your extension's stores/ directory, and you can follow the example of an existing store such as useLutPresentationStore.ts or useSynchronizersStore.ts.
Creating hooks
To create a hook, you can make one in your extension's hooks/ directory, and you can follow the example of an existing hook such as usePatientInfo.tsx.
Creating providers
To create a provider, you can make one in your extension's providers/ or contexts/ directory, and you can follow the example of an existing provider such as ViewportGridProvider.tsx.
Adding new icons
To add a new icon, you can add it to the icons/ directory, then register the icon using import { addIcon } from '@ohif/extension-default/src/utils'
Creating synchronizers
You can create custom synchronizers and place them in the synchronizers/ directory, you can follow the example of frameViewSynchronizer.ts
Utilites
Any new utilites should be placed in the utils/ directory, and you can follow the example of formatPN.ts
Commands
Commands are created in the commandsModule of the extension, for example the cornerstone extension has commandsModule.tsx, sometimes its also named getCommandsModule.tsx.
Overriding OHIF Components
To override an OHIF component, you can create a new component in your extension's components/ directory, then import it instead of the original ui-next component.
Mode layout
The layoutTemplate is a function that returns a layout object, you can follow the example of longitudinal/src/index.ts. This would be helpful when you need to override a component as you can know where to look for the original component.
Pub Sub
Always prioritrize pub sub, by calling a services subscribe over useEffects as it's more reliable, for example
useEffect(() => {
const subscriptions = [
cornerstoneViewportService.subscribe(EVENTS.VIEWPORT_DATA_CHANGED, handleViewportDataChanged),
syncGroupService.subscribe(EVENTS.VIEWPORT_REMOVED, onHotKeyRemoval),
syncGroupService.subscribe(EVENTS.VIEWPORT_ADDED, onHotKeyAddition),
];
return () => {
subscriptions.forEach(({ unsubscribe }) => unsubscribe());
};
}, []);
Never modify core architecture
Do not modify the core and always find a way to implement the solution via the extensions and modes, only modify core as a last resort if all other fail or there's an architectural constraint.
Skills
The ohif-test-agent skill (Playwright E2E test guidance) lives at .agents/skills/ohif-test-agent/.
Configuration
Plugin Configuration
Extensions are auto-discovered via pluginConfig.json and dynamically imported during build.
Medical Imaging Specifics
DICOM Support
- Multi-format: CT, MRI, X-Ray, Mammography, Ultrasound
- SOP Class handlers for specialized DICOM types (RT, SEG, SR)
- DICOMweb protocol for web-based image retrieval
Hanging Protocols
Define how images are arranged and displayed:
- Located in
hps/directories - JSON configuration with viewport rules
- Support for priors comparison and multi-monitor layouts
Measurement Tools
- Cornerstone Tools integration for annotations
- Bidirectional measurements, polylines, annotations
- Export capabilities (DICOM SR, CSV reports)
- AI-assisted measurements via ONNX models