API — ConceptExplorerCore
ConceptExplorerCore is the plugin ABI: the abstract types every extension dispatches on, the two structs that cross the Rust↔Julia boundary, and the contract functions. For the narrative version with examples, see The Dispatch ABI.
Of these, FileType, preview and matches are built; the rest are declared design targets with no implementation.
ConceptExplorerCore.ConceptExplorerCoreConceptExplorerCore.AnnotationKindConceptExplorerCore.ConceptEntityConceptExplorerCore.FileTypeConceptExplorerCore.PreviewPayloadConceptExplorerCore.TreeNodeConceptExplorerCore.applicable_annotationsConceptExplorerCore.ast_hashConceptExplorerCore.file_type_forConceptExplorerCore.file_typesConceptExplorerCore.matchesConceptExplorerCore.parse_entitiesConceptExplorerCore.previewConceptExplorerCore.read_within
ConceptExplorerCore.ConceptExplorerCore Module
ConceptExplorerCoreThe plugin ABI for Ship of Tools.
A small set of abstract types defines what is pluggable; methods on them are the contract. A package extends the system simply by being using-ed — the dispatch tables grow, with no registration step and no manifest.
The surface is three abstract types — FileType, ConceptEntity and AnnotationKind — plus two serialization structs, TreeNode and PreviewPayload, that carry opaque payloads across the Rust↔Julia boundary.
Implementation status: FileType is the surface that is wired end-to-end today — the seven standard file types ship as ordinary matches/preview methods with no privileged access, and third-party plugins (e.g. the HDF5 example) travel the identical path. The other two types are declared design seams: no concrete subtype of ConceptEntity or AnnotationKind exists yet. The current navigation modes are built into the frontend/backend. Future mods are specified by ADR 0051 and are not built.
See the Extending section of the manual — The Dispatch ABI and the Writing a FileType Plugin / HDF5 worked-example pages — for the full contract.
sourceConceptExplorerCore.AnnotationKind Type
AnnotationKindAbstract supertype for a category of LLM/user-authored annotation that can be attached to a ConceptEntity — type-meaning, math-derivation, and so on. applicable_annotations reports which kinds are valid for a given entity.
ConceptExplorerCore.ConceptEntity Type
ConceptEntityAbstract supertype for a conceptual unit a file declares — a function, type, module, or math derivation — as distinct from the file's raw bytes.
parse_entities extracts them from a file; ast_hash gives each a stable provenance key (used to detect annotation staleness), and applicable_annotations reports which AnnotationKinds may decorate it.
ConceptExplorerCore.FileType Type
FileTypeAbstract supertype for the kinds of file the explorer can preview and parse — PNG, Julia source, Markdown, JSON, and so on.
A plugin adds a kind with struct MyKind <: FileType end, declares which paths it claims with matches, and implements preview (and, where the kind declares concept entities, parse_entities). Loaded subtypes are discovered automatically by file_types; the best match for a path is resolved by file_type_for. Adding a FileType requires zero changes on the Rust side.
ConceptExplorerCore.PreviewPayload Type
PreviewPayload(mime, data, extras=Dict())A rendered preview crossing to the frontend: a MIME type, the raw data bytes, and an opaque extras dictionary for kind-specific metadata (for example "page"/"page_count" for paginated content). The frontend dispatches on mime to choose a renderer and never needs to learn about new entity kinds.
ConceptExplorerCore.TreeNode Type
TreeNode(id, label, kind; has_children=false, badges=Symbol[], payload=Dict())One node in a mode's navigation tree, and the unit of structure that crosses to the frontend. Fields:
id::String— opaque, kernel-defined identity (Rust never interprets it).label::String— display text.kind::Symbol— node kind for icon/coloring (:module,:function,:pngfile, …).has_children::Bool— whether the node can be descended into.badges::Vector{Symbol}— cross-cutting provenance/state marks (:stale,:user_edited,:immutable, …) rendered uniformly across every mode.payload::Dict{String,Any}— opaque, kind-specific data the kernel round-trips.
The keyword constructor fills the common defaults.
sourceConceptExplorerCore.applicable_annotations Function
applicable_annotations(e::ConceptEntity) -> Vector{Type{<:AnnotationKind}}Which annotation kinds can decorate this entity. Plugins extend.
sourceConceptExplorerCore.ast_hash Function
ast_hash(e::ConceptEntity) -> StringStable identifier for a concept entity's textual realisation. Used as the provenance key in .concept/ annotation frontmatter (synced_against).
ConceptExplorerCore.file_type_for Method
file_type_for(path) -> Union{Type{<:FileType}, Nothing}Best-match FileType for path. Each plugin's FileType subtype is expected to define matches(::Type{<:FileType}, path) -> Bool; the first match wins. Falls back to nothing when no plugin claims the path.
ConceptExplorerCore.file_types Method
file_types() -> Vector{Type{<:FileType}}Every loaded FileType subtype. Computed via subtypes(FileType) so the list grows automatically when an extension package is using-ed.
ConceptExplorerCore.matches Function
matches(::Type{<:FileType}, path) -> BoolPlugin contract: return true if this FileType should claim path. Phase-1 plugins typically inspect the file extension. The first plugin to return true gets the preview / parse_entities calls.
ConceptExplorerCore.parse_entities Function
parse_entities(::Type{<:FileType}, path) -> Vector{ConceptEntity}Extract the conceptual entities the file declares (modules, types, functions, etc.). Phase-1 returns an empty vector for unknown types.
sourceConceptExplorerCore.preview Function
preview(::Type{<:FileType}, path) -> PreviewPayload
preview(::Type{<:FileType}, path, params::AbstractDict) -> PreviewPayloadRender a file at path to a typed preview payload. Plugins extend this method on their own <:FileType subtype.
The 3-arg form carries request parameters (e.g. "page" for paginated content — ADR 0021). Callers (the kernel) always invoke the 3-arg form; the fallback below drops the params so 2-arg plugins work untouched. Paginated plugins override the 3-arg form and report position via PreviewPayload.extras (e.g. "page"/"page_count").
ConceptExplorerCore.read_within Method
read_within(cmd, seconds) -> Vector{UInt8}read(cmd) with a bound: when seconds pass the process is killed (KILL, so a tool that ignores TERM ends too) and its output pipe is closed, so a descendant still holding that pipe cannot hold the call; the error names the program and the bound. As read(cmd) does, it reads through open(cmd), whose stdin is devnull.