API — ConceptExplorerCore
ConceptExplorerCore is the plugin ABI: the abstract types every extension dispatches on, the two structs TreeNode and PreviewPayload, and the contract functions. For the narrative version with examples, see The Dispatch ABI.
Built and used: FileType, matches, preview, file_types, file_type_for, PreviewPayload (every plugin's preview returns one) and read_within (the PDF and video plugins run their tools through it). parse_entities has a method in every built-in plugin and no caller. Declared and not built: Mode, ConceptEntity, AnnotationKind, Tool, Capture, TreeNode (nothing outside core's tests builds one), ast_hash and applicable_annotations (no method). Which structs cross the Rust↔Julia seam is in the serialization seam.
ConceptExplorerCore.ConceptExplorerCoreConceptExplorerCore.AnnotationKindConceptExplorerCore.CaptureConceptExplorerCore.ConceptEntityConceptExplorerCore.FileTypeConceptExplorerCore.ModeConceptExplorerCore.PreviewPayloadConceptExplorerCore.ToolConceptExplorerCore.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 by being loaded in the kernel; today that means it is a dependency of julia/kernel plus a using line or a LAZY_PLUGIN_FOR_EXT row. Nothing loads a package from a user's project.
The surface is six abstract types — FileType, Mode, ConceptEntity, AnnotationKind, Tool and Capture — plus two structs, TreeNode and PreviewPayload. PreviewPayload is what preview returns, and the kernel re-encodes it for the wire; TreeNode is declared, and nothing outside core's tests builds one, because Rust builds every tree node. The Dispatch ABI in the manual describes the seam.
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 five types are declared design seams: no concrete subtype of Mode, ConceptEntity, AnnotationKind, Tool, or Capture exists yet, and the current navigation modes are built into the frontend/backend rather than dispatched through Mode.
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. Not built: no AnnotationKind subtype exists.
ConceptExplorerCore.Capture Type
CaptureAbstract supertype for a structured REPL output — a figure, a DataFrame, and the like — that should render at full fidelity rather than as text. A capture plugin defines capture_payload to convert the value into a display frame. Not built: no Capture subtype exists.
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, and applicable_annotations reports which AnnotationKinds may decorate it. Not built: no ConceptEntity subtype exists.
ConceptExplorerCore.FileType Type
FileTypeAbstract supertype for the kinds of file the explorer can preview and parse — PDF, 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 first claimant of a path is resolved by file_type_for. Adding a FileType needs no frontend change; a kind whose preview is bounded regardless of file size also needs its extensions in the daemon's is_bounded_output_plugin.
ConceptExplorerCore.Mode Type
ModeAbstract supertype for a switchable navigation-tree root — Files, Modules, Types, Math, Outputs, and the rest. Every mode presents the same shape — a parent → current → children hierarchy shown as a collapsible outline; a hotkey swaps which Mode's tree is the root, and cursor position is preserved per mode across switches.
A mode plugin implements the tree contract — tree_root, tree_children and preview_for — returning TreeNode values for the frontend to render and a PreviewPayload for the focused node. (No package defines these methods yet, and this module does not.)
ConceptExplorerCore.PreviewPayload Type
PreviewPayload(mime, data, extras=Dict())A rendered preview, as preview returns it: a MIME type, the raw data bytes, and an 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.Tool Type
ToolAbstract supertype for an action the orchestrator LLM can invoke. A tool plugin defines tool_spec (the schema advertised to the model) and tool_call (the implementation). Not built: no Tool subtype exists.
ConceptExplorerCore.TreeNode Type
TreeNode(id, label, kind; has_children=false, badges=Symbol[], payload=Dict())One node in a mode's navigation tree. Declared for the mode design; no Julia code builds one outside core's tests, because Rust builds every tree node. 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. Declared, not built: no method, no caller.
sourceConceptExplorerCore.ast_hash Function
ast_hash(e::ConceptEntity) -> StringStable identifier for a concept entity's textual realisation. Declared, not built: no method, no caller. Staleness today compares the SHA-256 of the file's bytes with synced_against.
ConceptExplorerCore.file_type_for Method
file_type_for(path) -> Union{Type{<:FileType}, Nothing}The first FileType whose matches is true for path. Each plugin's FileType subtype is expected to define matches(::Type{<:FileType}, path) -> Bool. 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. The built-in plugins inspect the file extension. The first plugin to return true gets the preview call (parse_entities has no caller).
ConceptExplorerCore.parse_entities Function
parse_entities(::Type{<:FileType}, path) -> Vector{ConceptEntity}Extract the conceptual entities the file declares (modules, types, functions, etc.). There is no generic method: a type without one raises a MethodError, and each built-in plugin returns an empty vector. Declared, not built: nothing calls it.
ConceptExplorerCore.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.