Imported from ysgao/OntoGraph-lite (
AGENTS.md). Install upstream withnpx skills add ysgao/OntoGraph-lite. Copyright stays with the author.
AGENTS.md
This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.
Project Overview
OntoGraph is a VS Code extension for OWL ontology editing, reasoning, and visualization. It provides a Protégé-like interface for OWL ontologies, with SNOMED CT-scale support.
Build Commands
TypeScript Extension
npm run build # Production build via esbuild (generates dist/)
npm run build:watch # Watch mode
npm run compile # Type-check extension (no emit)
npm run compile:webview # Type-check webview bundles (separate tsconfig)
npm run build:parser # Regenerate Manchester syntax parser from Peggy grammar
npm run package # Create .vsix for VS Code marketplace (--no-dependencies)
CLI Package (cli/)
pnpm --filter ontograph-cli build # Bundle cli/dist/main.js
pnpm --filter ontograph-cli test # Run CLI tests
node cli/dist/main.js --help # Try CLI locally
node cli/dist/main.js parse <file> # Core command example
Java Reasoner Server
cd java-server && mvn clean package # Builds fat JAR via maven-shade-plugin
The built JAR at java-server/target/onto-reasoner-server.jar is used at runtime. Rebuild only needed when changing Java code.
Running Tests
npm test # Run all tests (Vitest)
npm test -- src/parser/FunctionalParser.test.ts # Single test file
npm test -- src/serializer/FunctionalSerializer.test.ts # Serializer tests
npm run test:watch # Watch mode
Test files: src/parser/*.test.ts, src/parser/__tests__/*.test.ts, and src/serializer/*.test.ts. There are no Java tests.
Architecture
Three-tier design: TypeScript extension → Java reasoning server (JSON-RPC on stdin/stdout).
CLI Package (cli/): Standalone npm package ontograph-cli for AI tools. Two categories of commands:
- Core (no VS Code): parse, search, validate, convert — imports directly from
src/parser/,src/model/,src/serializer/via@corealias. - Bridge (requires running extension): classify, check-consistency, dl-query — connects to
src/bridge/BridgeServer.tsvia a Unix domain socket (path in~/.ontograph-lite/bridge.json).
src/api.ts defines OntoGraphApi — returned by activate() and used by BridgeServer as its dispatch target.
1. Extension Layer (src/extension.ts)
Activates the extension, registers commands and tree views (Classes, Properties, Individuals, Inferred Hierarchy), and holds the in-memory OntologyModel and OntologyIndex as module-level globals.
2. Parser Layer (src/parser/)
ParserRegistry detects format and dispatches to one of five parsers: FunctionalParser (.ofn), ManchesterParser (.omn), TurtleParser (.ttl/.n3), OwlXmlParser (.owl/.owx), RdfXmlParser. For large ontologies (above ontograph.largeOntologyThreshold, default 50k classes), parsing runs in a Worker Thread via parserWorker.ts to avoid blocking the extension host. The Manchester parser is generated from src/parser/manchester/owl-manchester.peggy via Peggy.
3. Model (src/model/)
OntologyModel.ts defines core types (OWLClass, ObjectProperty, DataProperty, Individual, axioms). OntologyIndex.ts provides fast lookup structures built post-parse. AxiomDisplay.ts handles how axioms are rendered in the UI.
4. Serializer Layer (src/serializer/)
FunctionalSerializer.ts round-trips the in-memory model back to OWL Functional Syntax. It uses a Protégé-style entity-cluster arrangement defined by the normative write spec ContentArrangementInOWLfunctionalSyntaxDocument.md:
Declarations → Object Property clusters → Data Property clusters →
Annotation Property clusters → Class clusters → GCI axioms → Property chains → )
Within each class cluster: annotations first (labels, then other), then EquivalentClasses, then SubClassOf, then DisjointClasses.
5. Sync Layer (src/sync/)
AnnotationSync.ts and AxiomSync.ts write changes back to the source file in-place without re-serializing the entire document. They parse prefix maps directly from the file text.
- For
.ofn/.omn: annotation and axiom sync are separate operations. - For
.ttl:AxiomSynchandles both structural and annotation segments in a single atomic edit to avoid VS Code document-version conflicts from two concurrentapplyEditcalls.
IRI abbreviation rule: The four RDFS built-in annotation property IRIs are written as abbreviated tokens: rdfs:label, rdfs:comment, rdfs:seeAlso, rdfs:isDefinedBy. All other IRIs — including entity IRIs, other annotation property IRIs, and class expression IRIs — use the full <IRI> bracket form. This matches Protégé output.
⚠️ OWL write format is normative — always consult the format spec. Any code that writes or modifies OWL Functional Syntax — the serializer (
FunctionalSerializer.ts), the in-place sync writers (AnnotationSync.ts,AxiomSync.ts), and entity creation (EntityCreationSync.ts) — MUST conform toContentArrangementInOWLfunctionalSyntaxDocument.md, the authoritative write specification (section & cluster ordering, blank-line separation, indentation matching, IRI abbreviation). Before changing how OWL files are produced or edited, read that document; if the behaviour must change, update the document in the same commit so spec and code stay in lock-step.
6. Commands Layer (src/commands/)
One file per VS Code command: classifyOntology, checkConsistency, exportOntology, addEntity, openVisualization, openSparqlEditor, openDLQuery. Commands read the shared activeModel/activeIndex from extension.ts.
7. Reasoner Bridge (src/reasoner/ReasonerBridge.ts)
Spawns the Java JAR as a child process and communicates via JSON-RPC. Sends requests (classify, checkConsistency, convertFormat, dlQuery) and returns inferred hierarchy/consistency/query results.
8. Java Server (java-server/src/main/java/org/ihtsdo/ontoeditor/)
ReasonerServer.java is the entry point (JSON-RPC on stdin/stdout). OntologyService.java wraps OWLAPI 5. Auto-selects HermiT (full OWL 2 DL) or ELK (scalable, for >5k classes) — threshold configurable via extension settings.
9. Views & Webviews (src/views/, webview-src/)
Tree providers populate the sidebar panels. Four webview bundles (graph, entity-editor, sparql-editor, dl-query) are built separately. Messages between extension and webviews are typed in src/views/*Messages.ts. DLQueryPanel.ts is a singleton panel for DL query execution; DLQueryState.ts exports the temporaryClassIris set used to inhibit sync-to-disk during in-flight queries.
10. LSP Server (src/lsp/)
A Language Server Protocol server (server/server.ts) provides completions and diagnostics for OWL files. Launched by client.ts as a separate Node process.
Build Outputs (dist/)
esbuild.mjs produces seven bundles:
| Bundle | Entry | Target |
|---|---|---|
extension.js |
src/extension.ts |
Node/CJS (extension host) |
parserWorker.js |
src/parser/parserWorker.ts |
Node/CJS (Worker Thread) |
server.js |
src/lsp/server/server.ts |
Node/CJS (LSP process) |
graph-webview.js |
webview-src/graph/GraphViewApp.ts |
Browser/IIFE |
entity-editor-webview.js |
webview-src/entity-editor/EntityEditorApp.ts |
Browser/IIFE |
sparql-editor-webview.js |
webview-src/sparql-editor/SparqlEditorApp.ts |
Browser/IIFE |
dl-query-webview.js |
webview-src/dl-query/DLQueryApp.ts |
Browser/IIFE |
Key Files
| File | Role |
|---|---|
src/extension.ts |
Extension activation; command + view registration; global model state |
src/model/OntologyModel.ts |
Core OWL data structures |
src/parser/ParserRegistry.ts |
Format detection and parser dispatch |
src/serializer/FunctionalSerializer.ts |
Model → OWL Functional Syntax |
src/sync/AxiomSync.ts |
In-place axiom writes back to source file |
src/sync/AnnotationSync.ts |
In-place annotation writes back to source file |
src/reasoner/ReasonerBridge.ts |
Java process lifecycle + JSON-RPC |
src/views/DLQueryPanel.ts |
Singleton DL query panel; TempClass lifecycle management |
src/views/DLQueryState.ts |
Exports temporaryClassIris set; inhibits sync during in-flight queries |
java-server/.../ReasonerServer.java |
Java entry point |
java-server/.../OntologyService.java |
OWLAPI 5 wrapper |
esbuild.mjs |
Build config — 7 output bundles |
ContentArrangementInOWLfunctionalSyntaxDocument.md |
Normative write spec for OWL Functional Syntax (ordering, blank lines, indentation, IRI abbreviation) — consult before any OWL-file write change |
Code Style
This project follows the Google TypeScript Style Guide (enforced via conductor/code_styleguides/typescript.md). Key rules:
const/letonly —varis forbidden- Named exports only — no default exports
- Single quotes for strings; template literals for interpolation
- No
anytype — preferunknownor a specific type - No type assertions (
as SomeType) unless unavoidable with justification UpperCamelCasefor types/interfaces/enums,lowerCamelCasefor variables/functions- No
_prefix or suffix on identifiers (including private fields) - No
publicmodifier (it's the default); useprivate/protectedto restrict ===and!==for equality; always explicit semicolons- No new runtime dependencies without documented rationale and explicit approval
Governance & Workflow
All development in this repository is governed by the OntoGraph Constitution, which supersedes other practices in case of conflict.
Conductor Workflow (conductor/)
The conductor/ directory contains project management documents:
tracks.md— top-level index of major work tracksproduct.md/product-guidelines.md— product vision and constraintsworkflow.md— full TDD workflow specificationcode_styleguides/— language-specific style rules- Per-track plan files in
conductor/tracks/<track>/plan.md
Task lifecycle (see conductor/workflow.md for full detail):
- Mark task
[~]inplan.mdbefore starting - Red phase: write failing tests first; confirm they fail before implementing
- Green phase: implement minimum code to pass tests
- Commit code; attach summary via
git notes add -m "<summary>" <sha> - Update task to
[x] <7-char-sha>inplan.md; commit withconductor(plan):scope
Quality gates before marking a task complete: all tests pass, coverage >80%, no type errors (npm run compile), OWL Functional Syntax ordering preserved, large ontology benchmark passes (test-ontologies/bfo-core.ofn).
Commit convention: <type>(<scope>): <description> where type is feat, fix, refactor, test, docs, or chore. Conductor commits use conductor(plan): scope.
Supported Formats
OWL Functional Syntax (.ofn), Manchester Syntax (.omn), OWL/XML (.owl/.owx), Turtle/N-Triples (.ttl/.n3).
Test Ontologies
test-ontologies/ contains sample files for manual testing:
animals.omn/animals.owx/animals.ttl— small examples for all formatsbfo-core.ofn— large (~94 KB) BFO ontology for performance testingpizza.owl— OWL/XML format example (~163 KB)bfo-classes-only.ofn— minimal BFO classes
OWL File Operations — Use the CLI
When working with .ofn, .omn, .ttl, .owl, .owx files, use ontograph rather than reading raw text:
ontograph parse <file> # entity counts, format, ontology IRI
ontograph search <file> <query> # find entities by label or IRI substring
ontograph validate <file> # structural error check
ontograph convert <file> --to functional # normalize to OWL Functional Syntax
All output is JSON on stdout. Exit 0 = success, non-zero = error (errorCode in JSON identifies type).
Bridge commands (require OntoGraph active in VS Code or compatible fork):
ontograph classify # run reasoner classification
ontograph check-consistency # OWL 2 DL consistency check
ontograph dl-query "<expr>" # Manchester Syntax DL query
Install: npm install -g @ysgao/ontograph-cli
Recent Changes
- 012-load-large-ontology:
loadOntologyFilecommand + toolbar button ($(folder-opened)) loads any-sized ontology viavscode.workspace.fs.readFile;createLargeFileListenershows notification for VS Code large-file conditions;reloadOntologyrefactored fromopenTextDocumenttoworkspace.fs.readFile;setupFileWatcherextracted fromhandleDocumentto shared helper - 011-autodetect-owl-syntax: Added TypeScript 5 (strict mode), Node.js 20 + VS Code Extension API (no new runtime deps)
- 010-reload-ontology: Added TypeScript 5 (strict mode), Node.js 20 + VS Code Extension API (
vscode.FileSystemWatcher,vscode.workspace.openTextDocument),ParserRegistry.parseAsync(existing)
Active Technologies
- TypeScript 5 (strict mode), Node.js 20 + VS Code Extension API,
vscode.workspace.fs(raw file I/O), existingParserRegistry.parseAsync, existingAnnotationSync/AxiomSync(012-load-large-ontology) - File system (read via
vscode.workspace.fs.readFile; write viaWorkspaceEdit+workspace.applyEdit) (012-load-large-ontology)
