Repository navigation
Releases: aehrc/codeagogo
Releases · aehrc/codeagogo
Release list
Codeagogo v1.2.0
Fixed
- ECL Workbench concept typeahead: Concept search suggestions now appear reliably once typing pauses. Previously results were only shown on the next keystroke and were computed for the previous text, so typeahead often appeared not to activate (fixed upstream in ecl-editor-core 1.6.1).
- ECL Workbench shortcut hint: The hint bar now shows
⌃+Spacefor autocomplete on macOS. It previously showed⌘+Space, which opens Spotlight and never triggered autocomplete (ecl-editor 1.6.2). - Format / Simplify ECL: Constraint operators on refinement attribute names (e.g.
<< 363698007 = …) are no longer silently dropped, and alternate identifiers, numeric/string comparisons and member field selections now survive formatting (ecl-core 1.6.0). - Settings window on smaller screens: The Settings window had a fixed 1060pt height, so on shorter displays (such as a 13" MacBook Air) its bottom extended off-screen and the logging and diagnostics controls could not be reached. It now opens at most as tall as the screen's visible area, scrolls when the content doesn't fit, and can be resized between 480pt and its full height.
Changed
- ecl-core 1.6.2: Updated from 1.1.2. Also adds parsing of the top/bottom of set operators (
!!>,!!<). - ecl-editor 1.6.2: ECL Workbench bundle rebuilt from the ecl-lsp v1.6.2 tag.
- Monaco 0.57.0: ECL Workbench now loads Monaco 0.57.0 (was 0.52.2), matching the version ecl-lsp is tested against.
- Bumped build-time
esbuild0.28.1 → 0.28.2.
[1.1.1] - 2026-06
[1.2.0] - 2024-11
Added
- Copy buttons for ID & FSN and ID & PT combinations
- Pipe-separated format for combined copy operations
Changed
- Updated button layout in popover
Codeagogo v1.1.1
Fixed
- Replace Inactive: Fixed chained-regex replacement that could corrupt output when one inactive concept's replacement target SCTID matched another inactive concept's ID in the same selection. Replacements are now located by position against the original text and applied in reverse order, mirroring Replace Selection (issue #2). The completion message now reports the number of concepts actually replaced (rather than the number attempted) and logs a warning if any concept with a replacement could not be located in the text.
Security
- Bumped build-time
esbuild0.25.12 → 0.28.1, clearing advisory GHSA-gv7w-rqvm-qjhr (npm audit: 0 vulnerabilities). Build-time only — esbuild is not shipped in the app; the ecl-core bundle was regenerated and verified.
Codeagogo v1.1.0
Features
- Simplify ECL (
Shift+Control+Option+E): One-way simplification of ECL expressions — removes redundant parentheses and formats. Derived from the Format ECL hotkey by adding Shift. - Replace Inactive Concepts (
Control+Option+I): Select ECL containing inactive SNOMED CT concepts and replace them with active equivalents from historical associations (REPLACED BY, SAME AS, POSSIBLY EQUIVALENT TO, ALTERNATIVE) viaConceptMap/$translate. - Canonical ECL Comparison:
canonicalise()andcompareExpressions()in ECLBridge for structural equivalence checking without FHIR calls. - Menu Hotkey Display: All menu items now show the configured global hotkey shortcut in italics, updating dynamically when settings change.
- ecl-core 1.1.2: Updated to ecl-core 1.1.2 with
removeRedundantParenthesesformatter option, canonical comparison, and historical association lookups. - ecl-editor 1.1.2: Updated ECL Workbench bundle — inactive concept replacement quick fixes, shared language registration fix, toggle display terms (Shift+Alt+T), cleaner embedded appearance.
- Concept Lookup (
Control+Option+L): Select any clinical code and see its details in a popover near your cursor — concept ID, display term, FSN, active/inactive status, edition, and code system. Supports SNOMED CT, LOINC, ICD-10, RxNorm, and configurable code systems via FHIR R4 terminology servers. - Concept Search (
Control+Option+S): Search for concepts by term and insert the result directly into any text field. Configurable result limits and insert format. - Batch Replace (
Control+Option+R): Select one or more codes and annotate them withID | display term |format. Handles SNOMED CT, LOINC, ICD-10, and other alphanumeric codes across all available editions. - ECL Workbench (
Control+Option+V): Full-featured ECL editing environment with Monaco-based editor, syntax highlighting, FHIR-powered autocomplete, inline diagnostics, formatting, and live evaluation. Powered by@aehrc/ecl-editor. - ECL Format (
Control+Option+E): Toggle ECL expressions between pretty-printed and minified format with 9 configurable options. Powered by@aehrc/ecl-corevia JavaScriptCore. - Open in Shrimp (
Control+Option+H): Open selected SNOMED CT concept in Shrimp browser. - Concept Diagrams: SNOMED CT concept definition diagrams following the Diagramming specification, with SVG/PNG export. Locale-aware preferred terms and composite unit resolution (e.g., "mg/mL").
- ECL Reference Panel: 50 searchable knowledge articles covering all ECL operators, grouped by category.
- Semantic Validation: Background validation of concepts in ECL expressions with warnings for inactive or unknown concepts.
- Update Checker: Automatic checks for new releases (on launch + daily), with orange dot badge on menu bar icon, menu notification, and Settings banner.
- Launch at Login: Opt-in on first launch via welcome screen, configurable in Settings.
- Homebrew Tap: Install via
brew tap aehrc/codeagogo && brew install --cask codeagogo. - Custom Menu Bar Icon: Ontoserver-style cloud with network dots.
- Configurable Hotkeys: All six hotkeys fully customizable via Settings using a keystroke recorder.
- Multi-Code-System Support: Configurable additional code systems via Settings, queried via FHIR
CodeSystem/$lookup. - Anonymous Install Metrics: Random UUID in User-Agent for install counting — no personal data collected.
- Welcome Screen: First-launch onboarding with mailing list and GitHub links.
Security
- XSS prevention in WebView rendering
- Input size and depth limits on all parsers
- HTTPS enforcement with ATS configuration
- Gitleaks secrets scanning in CI
- Apache 2.0 license headers on all source files
Codeagogo v1.0.0
Features
- Concept Lookup (
Control+Option+L): Select any clinical code and see its details in a popover near your cursor — concept ID, display term, FSN, active/inactive status, edition, and code system. Supports SNOMED CT, LOINC, ICD-10, RxNorm, and configurable code systems via FHIR R4 terminology servers. - Concept Search (
Control+Option+S): Search for concepts by term and insert the result directly into any text field. Configurable result limits and insert format. - Batch Replace (
Control+Option+R): Select one or more codes and annotate them withID | display term |format. Handles SNOMED CT, LOINC, ICD-10, and other alphanumeric codes across all available editions. - ECL Workbench (
Control+Option+V): Full-featured ECL editing environment with Monaco-based editor, syntax highlighting, FHIR-powered autocomplete, inline diagnostics, formatting, and live evaluation. Powered by@aehrc/ecl-editor. - ECL Format (
Control+Option+E): Toggle ECL expressions between pretty-printed and minified format with 9 configurable options. Powered by@aehrc/ecl-corevia JavaScriptCore. - Open in Shrimp (
Control+Option+H): Open selected SNOMED CT concept in Shrimp browser. - Concept Diagrams: SNOMED CT concept definition diagrams following the Diagramming specification, with SVG/PNG export. Locale-aware preferred terms and composite unit resolution (e.g., "mg/mL").
- ECL Reference Panel: 50 searchable knowledge articles covering all ECL operators, grouped by category.
- Semantic Validation: Background validation of concepts in ECL expressions with warnings for inactive or unknown concepts.
- Update Checker: Automatic checks for new releases (on launch + daily), with orange dot badge on menu bar icon, menu notification, and Settings banner.
- Launch at Login: Opt-in on first launch via welcome screen, configurable in Settings.
- Homebrew Tap: Install via
brew tap aehrc/codeagogo && brew install --cask codeagogo. - Custom Menu Bar Icon: Ontoserver-style cloud with network dots.
- Configurable Hotkeys: All six hotkeys fully customizable via Settings using a keystroke recorder.
- Multi-Code-System Support: Configurable additional code systems via Settings, queried via FHIR
CodeSystem/$lookup. - Anonymous Install Metrics: Random UUID in User-Agent for install counting — no personal data collected.
- Welcome Screen: First-launch onboarding with mailing list and GitHub links.
Security
- XSS prevention in WebView rendering
- Input size and depth limits on all parsers
- HTTPS enforcement with ATS configuration
- Gitleaks secrets scanning in CI
- Apache 2.0 license headers on all source files
Added
- Initial release
- Global hotkey activation (Control+Option+L)
- SNOMED CT concept lookup via FHIR terminology server
- Popover display near cursor with concept details:
- Concept ID
- Fully Specified Name (FSN)
- Preferred Term (PT)
- Active/inactive status
- Edition and version information
- Copy buttons for individual fields
- Configurable hotkey (key and modifiers)
- In-memory caching with 6-hour TTL
- Multi-edition fallback search
- Menu bar integration
- Settings window
- macOS app icon
- Installation guide
- Privacy policy
- README documentation
Technical
- SwiftUI-based user interface
- Carbon framework for global hotkey registration
- App Sandbox with network client entitlement
- Accessibility permission for selection capture
Codeagogo v0.9.0
Added
- Concept visualization panel: New "Visualize" button in lookup popover opens a floating panel showing concept properties and relationships
- SNOMED CT concepts display relationship diagrams following SNOMED CT Diagramming specification
- LOINC and other code systems display property lists with colored boxes
- WebView-based rendering with HTML/SVG
- Lazy loading: properties fetched only when visualization is requested via
property=*parameter - Panel positioned to right of popover (or left if insufficient space)
- Meaningful export filenames: SVG/PNG downloads use sanitized concept terms (e.g.,
51451002-arthrotomy-of-glenohumeral-joint.svg)
- Shrimp browser integration (Control+Option+H): New hotkey and "Open in Shrimp" button to view concepts in the Shrimp terminology browser
- Shrimp URL builder supports SNOMED CT, LOINC, ICD-10, RxNorm, and other code systems with correct version and ValueSet parameters
Fixed
- Concept ID extraction now includes IDs starting with 1: Fixed regex pattern that incorrectly excluded valid SNOMED CT concept IDs starting with 1 (e.g., 10971007, 17756004, 179419004). These concepts now display correctly in visualizations with proper definition status.
Technical
- Added SNOMEDExpressionParser.swift: Complete parser for SNOMED CT compositional grammar
- Parses normalForm/normalFormTerse properties following SNOMED CT expression syntax
- Supports definition status (=== for defined, <<< for primitive)
- Parses focus concepts, refinements, attribute groups, and attributes
- Handles concept references with pipe-delimited terms
- Supports concrete values and nested expressions
- Added VisualizationModels.swift: ConceptProperty, PropertyValue enum, VisualizationData wrapper
- Updated DiagramRenderer.swift: SVG generation following SNOMED CT Diagramming Specification
- Parses normal form using SNOMEDExpressionParser
- Prioritizes normalForm (with human-readable terms) over normalFormTerse (IDs only)
- Preprocesses normal form to remove line breaks and normalize whitespace before parsing
- Renders focus concept, definition status symbol (≡ or ○), and parent concept
- Draws attribute groups with filled circles, ungrouped attributes with open circles
- Renders attributes as tan rounded rectangles, values as blue rectangles
- Generates connecting lines with proper junction points
- Falls back to text display if parsing fails
- Added VisualizationViewModel.swift: Async property loading and state management
- Added VisualizationPanelView.swift: SwiftUI view with WebView rendering
- Added VisualizationPanelController.swift: Panel window lifecycle (follows SearchPanelController pattern)
- Extended OntoserverClient with
lookupWithProperties(conceptId:system:version:)method - Extended FHIRParameters.Part with
valueIntegerfield for integer property values - Extended LookupViewModel with
onVisualizecallback andopenVisualization()method - Extended PopoverView with "Visualize" button
- Extended AppDelegate with VisualizationPanelController instance and callback wiring
- Extended CursorAnchorWindow with public
nsWindowaccessor for positioning - Added ShrimpURLBuilder.swift for constructing Shrimp browser URLs from concept lookup results
- Added ShrimpHotKeySettings.swift for configuring the Shrimp hotkey (default: Control+Option+H)
- Extended LookupViewModel with
openInShrimp()andlookupAndOpenInShrimp(from:)methods - Extended SettingsView with Shrimp Browser Hotkey configuration section
- Extended PopoverView with "Open in Shrimp" button
- Shrimp URLs include dynamic FHIR endpoint, concept ID, version/module information, and code system-specific ValueSet URIs
- User-Agent header: All FHIR requests now include
User-Agent: Codeagogo/{version} (macOS)for server log identification - Filename sanitization: VisualizationPanelView.swift includes
sanitizeFilename()function that removes semantic tags, sanitizes special characters, and truncates to ~40 chars - DiagramRenderer.swift passes concept ID and term through JavaScript postMessage for download operations
- Fixed regex pattern in VisualizationViewModel.swift and DiagramRenderer.swift from
\b([2-9]\d{5,17})\bto\b(\d{6,18})\bto match all valid SNOMED CT concept IDs
Codeagogo v0.8.0
Added
- Inserted text remains selected: After using the replace hotkey or ECL format hotkey, the inserted text is automatically selected, making it easy to undo or further edit. Selection skipped for text > 1000 characters to avoid delays
- Inactive concept highlighting: The popover now prominently displays inactive concepts with an orange warning icon and "INACTIVE" label
- "INACTIVE - " prefix option: New setting (default: on) prefixes inactive concept terms with "INACTIVE - " when using the replace hotkey (e.g.,
146066001 | INACTIVE - Some term |) - Hotkey recorder UI: Settings now uses a keystroke recorder control for configuring hotkeys. Click "Record" and press your desired key combination instead of selecting from dropdown menus and checkboxes.
- Multi-code-system support: Lookup, replace, and search now work with LOINC, ICD-10, RxNorm, and other code systems in addition to SNOMED CT
- Code system picker in search panel: Switch between SNOMED CT and configured code systems when searching
- Code system configuration in Settings: Add, remove, and enable/disable code systems from the terminology server
- SCTID validation: Uses Verhoeff check digit algorithm to distinguish valid SNOMED CT IDs from other numeric codes
- ECL Format hotkey (Control+Option+E): Toggles selected ECL expressions between pretty-printed and minified formats
- Full ECL 2.x parser supporting constraint operators, compound expressions, refinements, and filters
- Settings UI for configuring ECL format hotkey key and modifiers
- Progress HUD for replace hotkey: Shows lookup progress when processing many concepts
Changed
- App renamed to Codeagogo: The app has been renamed from "SNOMED Lookup" to "Codeagogo" to better reflect its expanded functionality beyond SNOMED CT lookups. Bundle identifier changed to
au.csiro.Codeagogo.
Fixed
- Inactive concept status: Fixed issue where inactive concepts were incorrectly displayed as active. The FHIR response parser now correctly handles the
inactiveproperty when returned as a boolean value. - Replace hotkey reliability: Fixed issue where some concept IDs weren't being replaced when processing large selections (50+ concepts)
Performance
- Replace hotkey is now ~15x faster: Uses batch lookup via
ValueSet/$expandto fetch all concept terms in a single API request (~0.5s for 62 codes vs ~7+ seconds with individual lookups) - Batch lookup integrates with existing concept cache: cached concepts are returned instantly, only uncached codes are fetched from the server
Changed
- ECL Format hotkey now toggles between pretty-printed and minified formats:
- If ECL is minified or irregular → pretty-print it with indentation and line breaks
- If ECL is already pretty-printed → minify it to a single line
- Pressing the hotkey repeatedly toggles between formats
- Replace hotkey now has smart toggle behavior:
- Finds all SNOMED CT codes in the selection, looks them up in parallel
- If a code has no term or wrong term → adds/updates the
| term |suffix - If ALL codes already have correct terms → removes all
| term |suffixes (toggle off) - Pressing the hotkey repeatedly toggles between "with terms" and "without terms"
- Example flow:
385804009→385804009 | Diabetic care |(add)385804009 | Diabetic care |→385804009(remove, since correct)385804009→385804009 | Diabetic care |(add again)
- Mixed selections work:
385804009 | Wrong | and 73211009updates both
Changed
- Lookup hotkey now automatically detects whether a code is SNOMED CT (via Verhoeff check) or from another code system
- Popover view adapts display based on code system: shows FSN/PT/Edition for SNOMED CT, simpler Code/Display/System for others
- Replace hotkey handles mixed selections with both SNOMED CT and non-SNOMED codes
Technical
- App now prompts for Accessibility permission on launch via
AXIsProcessTrustedWithOptionsfor reliable text selection - Extended SystemSelectionReader with Accessibility API methods (
getSelectionRange,setSelectionRange,pasteAndSelect) to select inserted text after paste operations - Selection fallback uses character-by-character keyboard simulation (Shift+Left Arrow) for precise selection up to 1000 chars
- Added HotKeyRecorderView.swift for recording keyboard shortcuts via keystroke capture
- Added KeyCodeFormatter.swift for formatting key codes with macOS modifier symbols (⌃⌥⇧⌘)
- Refactored hotkey settings to use KeyCodeFormatter for human-readable hotkey display
- Simplified SettingsView by removing Picker/Toggle-based hotkey configuration
- Added KeyCodeFormatterTests.swift with comprehensive tests for key formatting
- Added SCTIDValidator.swift with Verhoeff check digit algorithm for SNOMED CT ID validation
- Added CodeSystemSettings.swift for managing configured code systems (persisted to UserDefaults)
- Added AvailableCodeSystem struct for code systems discovered from the server
- Extended ConceptResult with
systemfield andsystemName/isSNOMEDCTcomputed properties - Added
getAvailableCodeSystems()method to OntoserverClient for fetching non-SNOMED code systems - Added
lookupInCodeSystem()method for looking up codes in specific code systems - Added
lookupInConfiguredSystems()method for parallel search across configured systems - Added
searchInCodeSystem()method for searching within non-SNOMED code systems - Extended LookupViewModel with
ExtractedCodestruct andextractCode()method for SCTID validation - Updated
extractAllConceptIds()to includeisSCTIDflag in ConceptMatch - Extended ConceptLookupClient protocol with
lookupInConfiguredSystems()method - Updated SearchSettings with
selectedCodeSystemURIfor code system selection - Updated SearchViewModel to handle non-SNOMED code system searches
- Updated SearchPanelView with code system picker (edition picker hidden for non-SNOMED)
- Updated SettingsView with "Additional Code Systems" configuration section
- Updated PopoverView to show adapted UI for SNOMED CT vs non-SNOMED results
- Added SCTIDValidatorTests.swift with 20+ tests for Verhoeff validation
- Added CodeSystemSettingsTests.swift for settings and ConceptResult code system tests
- Extended OntoserverClientTests.swift with multi-code-system response parsing tests
- Extended ConceptIdExtractionTests.swift with SCTID validation and ExtractedCode tests
- Added ProgressHUD.swift for displaying lookup progress near cursor
- Added
batchLookup(conceptIds:)method to OntoserverClient usingValueSet/$expandfor efficient multi-concept lookup BatchLookupResultincludes active status viaproperty=inactiveparameter (parsed from FHIR R5 property extension)- Added
BatchLookupResultstruct to hold PT, FSN, and active status mappings from batch lookups - Added ECLToken.swift with token type definitions for ECL syntax elements
- Added ECLLexer.swift for tokenizing ECL expressions (handles operators, identifiers, literals)
- Added ECLAST.swift with AST node types (expressions, refinements, attributes, filters)
- Added ECLParser.swift as a recursive descent parser for ECL 2.x grammar
- Added ECLFormatter.swift for pretty-printing AST back to formatted ECL text
- Added ECLMinifier struct for producing compact single-line ECL output
- Added
minifyECL()andtoggleECLFormat()public functions - Added ECLFormatHotKeySettings singleton for hotkey configuration
- Extended SettingsView with ECL Format Hotkey section
- Added 57 unit tests for ECL lexer, parser, formatter, minifier, and hotkey settings
- Extended
ConceptMatchstruct withexistingTermfield to track pipe-delimited terms - Updated
extractAllConceptIds(from:)to detect existing| term |patterns - Refactored
replaceSelection()with toggle logic for add/update/remove modes - Added unit tests for existing term detection and toggle simulation
v0.7.0
Added
- Replace hotkey (Control+Option+R): Looks up selected concept ID and replaces it with
ID | term |format - Configurable term format for replace: FSN (default) or PT
- Settings UI for replace hotkey key, modifiers, and term format
Technical
- Added ReplaceHotKeySettings singleton for replace hotkey configuration
- Added ReplaceSettings singleton for replace term format preference
- Added replaceSelection() action in AppDelegate
- Extended SettingsView with Replace Hotkey section
- Added unit tests for replace hotkey settings and term format
- Added UI tests for replace hotkey settings controls
v0.6.0
What's New
Concept Search and Insert
- New global hotkey (Control+Option+S) opens a floating search panel
- Typeahead search using FHIR ValueSet/$expand API to find concepts by term
- Edition selector: filter by specific SNOMED CT edition or search across all editions
- Insert format selector: choose between ID, PT, FSN, ID|PT, or ID|FSN formats
- Text insertion via simulated Cmd+V paste into any application
- Search panel shows Preferred Term, FSN (if different), concept ID, and edition name
Settings
- Configurable search hotkey (key and modifiers)
- Default insert format preference
Bug Fixes
- Search results deduplicated by concept code
- Unknown edition IDs fall back to CodeSystem title from server
Testing
- Added UI test automation (34 XCUITest tests)
- Added SearchViewModel mock-based unit tests (10 tests)
- Total test count: 91 unit tests + 34 UI tests
See CHANGELOG.md for full details.
SNOMED Lookup v0.5.0
- Focus taken when the popup opens to allow easy closing with the escape key
<<<<<<< HEAD
Changed
- Popover now takes focus when opened, allowing immediate dismissal with Escape key
- Focus is restored to the previously active application when the popover closes
=======
SNOMED Lookup v0.4.0
Added
- GitHub Actions release workflow for creating versioned releases
- GitHub Actions CI/CD workflow for automated builds and tests
- Downloadable build artifacts from CI (macOS app bundle)
- Comprehensive unit and integration test suite (63 tests)
- LRU cache with configurable size limit (100 entries)
- Retry logic with exponential backoff for transient network failures
- Dependency injection protocols for improved testability
- Accessibility labels for VoiceOver support
OntoserverErrorenum for structured error handling- Architecture documentation (ARCHITECTURE.md)
- Contributing guidelines (CONTRIBUTING.md)
- This changelog
Changed
- Consolidated duplicate modifier conversion code into
HotKeySettings.carbonModifiers - Improved memory management in GlobalHotKey with proper event handler cleanup
- Enhanced README with comprehensive documentation
- Replaced force unwraps with proper error handling in OntoserverClient
Removed
- Unused
ContentView.swiftplaceholder - Unused
SnowstormClient.swift(superseded by OntoserverClient) - Unnecessary imports (AppKit from app entry point, Combine from SettingsView)
Fixed
- GlobalHotKey memory leak from unregistered Carbon event handlers
- Potential crashes from force unwraps in URL construction