Changelog

0.31.1b1

Released:

30.07.2026

pre-release:

Five arcs this release: openCypher becomes the needs query language (CLI, MCP and the IDE filter boxes); Intersphinx brings cross-project references to the IDE and preview; the preview renders the sphinx-needs view directives (needlist / needtable / needflow) plus substitutions, toctrees, tables and much more markup; ubc check becomes the canonical project linter for CI; and Pharaoh gains an in-editor Agent panel that drives Claude Code, Mistral Vibe or OpenCode. Also: codelinks learns preprocessor-aware C/C++, Go and Bash, and remote needs.json sources are cached and served stale instead of vanishing on a failed fetch.

✨ openCypher queries

  • A real openCypher engine replaces the previous pseudo-cypher filter dialect. The project is queried as a property graph — each need a node labelled by its type, each typed link a relationship — supporting MATCH / OPTIONAL MATCH, WHERE, WITH, UNWIND, RETURN, UNION, ORDER BY / SKIP / LIMIT, aggregation, variable-length paths, EXISTS / COUNT subqueries and the openCypher function library (read-only, with query limits). It powers the new ubc query cypher subcommand, the Needs Index / Needs JSON filter boxes in VS Code (a bare expression over n still works), and the ubCode-only :cypher: option on the view directives below. See the query guide — and the migration notes under Breaking Changes.

  • MCP: ``query_cypher`` and ``get_graph_schema`` — AI agents query the needs graph with real openCypher and discover the schema (labels, link types, properties and available parameters, Neo4j-style), replacing the previous three needs tools (see Breaking Changes). Result tables are capped, with honest truncation notes and paging guidance.

  • Project context as query parameters — the reserved parameters $var (variant data, e.g. $var.deploy.region), $build_tags and $docname bridge project context into queries, and every node carries a computed docname property. An unknown parameter errors, naming the available ones.

  • Typo guards — a label, relationship type or property absent from the whole schema warns with a “did you mean” suggestion (on stderr in the CLI; as note: lines in MCP); the new ubc query cypher --strict flag turns these warnings into a failure.

  • Python-dialect parity and friendlier errors — bare True / False literals (the upstream total-count idiom for :need_count:), literal-on-the-left comparisons ("spec" == type) and the is_need / is_part constants now parse, so filters written for sphinx-needs stop failing whole views (18 → 4 view failures on the sphinx-needs docs corpus). Filter parse errors now name the offending position, unknown fields get “did you mean” suggestions, and the deliberately unsupported forms are documented with workarounds (see Differences from a Sphinx build).

✨ Intersphinx — cross-project references

  • :ref: and :term: references that miss locally now resolve against external Sphinx inventories configured in the new [intersphinx] section — in the IDE and in the preview, where they hydrate to real links carrying the target project’s titles and an ↗ marker. The explicit :external:role: / :external+inv:domain:role: family is ported too, for both reStructuredText and MyST.

  • IDE support is offline-capable:ref: completion includes external labels, hover shows the resolved title and URL, and every externally resolved site becomes a ctrl+clickable link. Inventories are cached per user with conditional revalidation; fetch problems surface as intersphinx.* warnings and never fail a build; offline = true pins the cache for network-restricted CI.

  • New ubc intersphinx CLIinspect <file-or-url> prints any inventory (Sphinx- or JSON-formatted, filterable), and cache dir | list | clean manages the cache.

✨ Preview

  • The sphinx-needs view directives renderneedlist and needtable (sticky header, projected columns, :columns: / :sort: validated with suggestions) render live filtered views hydrated from the index, :need_count: counts inline (including the a ? b percentage form), and needflow draws a real traceability graph — typed coloured nodes, per-link-type edges, legend — as a client-side Mermaid flowchart. Needs are selected via the shared Python filter surface or the ubCode-only :cypher: option, and a failed view renders an error block naming the reason. See the new needs tutorial.

  • Substitutions expand|name| references resolve from your replace / unicode / date definitions plus the Sphinx specials |version| / |release| / |today| (new [project] keys release, today, today_fmt); document titles and :ref: labels use the expanded text everywhere (hover, Site Map, needs.json); undefined, circular and runaway definitions are diagnosed (substitution.*).

  • Toctrees and the Site Map.. toctree:: renders as a nested list of links (a :hidden: toctree as a collapsed block); the new Site Map view shows the project’s navigation tree from the configured [project] root_doc; new toctree.* diagnostics report structural problems (missing documents, cycles, documents not included anywhere — :orphan: exempts); and ubc build list-documents gains --order <toctree|path>.

  • Tables buildlist-table, csv-table (including :file:, a tracked dependency) and table render as real tables.

  • literalinclude renders the included file as a highlighted code block with Sphinx’s filter pipeline (:lines:, :start-after: / :end-before:, :dedent:, :prepend: / :append:, …), as a tracked dependency, with honest diagnostics for the unsupported rest.

  • The raw directive passes through, with trust controls.. raw:: html emits its payload verbatim, in block position and inside substitution definitions (an rst_prolog-defined |br| finally works). The new [parse] key raw_enabled = false makes every raw directive inert (directive.raw_disabled plus an escaped placeholder) for pipelines that build unreviewed contributions, and the preview escapes raw HTML in untrusted workspaces. See Raw content.

  • The only directive renders conditionally — its tag expression is evaluated against build_tags; a falsy body shows as a collapsed greyed block in the preview and is excluded from the index (its needs and targets do not resolve, matching Sphinx).

  • Markdown hosts splice files too — MyST {include}, {literalinclude}, {csv-table} and {raw} with :file: now read their files on every surface, with cycle detection (which a Sphinx build lacks entirely).

  • sphinx-design components and :octicon:grid, card, dropdown, div and the button directives render with sphinx-design’s own markup (structure only in the preview for now — styling follows), button-ref and card :link: options participate in reference resolution, and :octicon: renders real inline icons.

  • Built-in extension ports — the new [parse] key extensions enables ported Sphinx extensions under their conf.py names: sphinxcontrib.video (video renders a real HTML5 player; playback inside the VS Code webview is still limited), sphinx.ext.extlinks (link-shorthand roles declared in [parse.extlinks]), and sphinx_syntax_example — a new syntax-example directive (its Sphinx twin published to PyPI as sphinx-syntax-example) that shows markup as highlighted source plus rendered result, with opt-in per-document numbering (syntax_example_numbering). Ported directives join autocomplete and hover. See Parsing.

  • Highlighting and pinningrst, myst and cypher code blocks now highlight, plus jinja, powershell, bat, cmake and latex; and a new 📌 pin toggle holds the preview on its document instead of following the active editor.

✨ Indexing & needs data

  • Included content reaches cross-file features.. include:: and rst_prolog / rst_epilog are now spliced on the index path too, so targets, needs and glossary terms defined there resolve project-wide, and references bound via default-role or custom roles are collected like an explicit :ref:.

  • Dangling hyperlink references are reported — an unresolved, duplicated or circular named hyperlink reference (target_, and the backtick-quoted phrase form) is diagnosed (ref.* codes) in the editor and ubc check.

  • Remote needs sources: cached, revalidated, stale-served — the new [needs.remote] section (cache_days, timeout, offline) governs every needs.json fetched over HTTP(S); a failed refetch now keeps the previously loaded needs and reports the failure (previously the needs silently vanished for 24 hours), revalidation is conditional (ETag / Last-Modified), and file:// URLs work.

✨ ubc check — the canonical project linter

  • Whole-project by defaultubc check (no arguments) now indexes and lints the entire project, Markdown included, reporting everything the editor reports (needs, reference, toctree and schema diagnostics included); ubc check <paths> scopes the findings to the given paths; --per-file restores the old isolated single-file behaviour. See linting on the command line.

  • Severity-aware exit policy — findings are summarised by severity (Found 1 error(s), 2 warning(s).), and the new --deny <info|warning|error> and --max-warnings <N> flags (on both ubc check and ubc build index) control what fails the run.

  • --output-format json — machine-readable diagnostics on stdout (code, severity, message, source locations), with the human progress chatter demoted to stderr.

🤖 Pharaoh (experimental)

Still experimental (ubc agent remains hidden); see the Pharaoh documentation.

  • The Pharaoh Agent panel — a new sidebar chat that runs an external coding agent in your workspace over the Agent Client Protocol: Claude Code, Mistral Vibe or OpenCode (GitHub Copilot keeps its native chat). The agent sees the project’s installed skills, asks inline before touching files or running commands (with a per-session auto-approve), and gets the ubc MCP tools. Provider API keys come from the environment — Claude Code needs an Anthropic Console ANTHROPIC_API_KEY (subscription logins are not permitted over ACP); keyless setups degrade to copyable prompts.

  • Harness-aware Drive and Run QA — the ubcode.agent.id setting now routes Drive / Capture intent to Copilot Chat, the Pharaoh panel, or plain clipboard copy (other), with always-available copy-prompt buttons; Run QA scores through the selected agent too (pin a different one with ubcode.qualityAnalysis.agentId to avoid self-review). Prompts name the bundled, version-matched ubc.

  • Documentation grounding — new MCP tools search_docs and fetch_doc_page ground any agent on the published ubCode and sphinx-needs documentation (symbol-aware: an exact needs_types hit outranks keyword matches), and the @pharaoh participant now uses the same engine-side retrieval, degrading gracefully when the docs are unreachable. The Clear documentation cache command is gone (the cache is now session-scoped).

  • Portable skills, better onboardingubc agent install additionally writes skills to the harness-neutral .agents/skills/ location (read by Mistral Vibe and OpenCode), and install --detect now derives per-type skills and a [quality] section, so Run QA works right after onboarding an existing project.

👌 Improvements

  • Directive diagnostics now underline the offending option name (or the directive name) instead of the whole directive block.

  • ubc build targets derives every objects.inv anchor and display name through the exact docutils / Sphinx rules, so external projects linking into yours land on anchors that exist.

  • The PlantUML-to-Mermaid preview conversion decodes display-text escapes (\n line breaks in notes, labels and member names) and renders multiple stereotypes.

  • The Pharaoh chat transcript renders full Markdown (tables, task lists, nested lists) with bounded parsing, so a pathological reply degrades to plain text instead of freezing the panel.

  • The ubCode sidebar is reordered (everyday views first), and the Site Map gained a pinnable Project row showing the followed file and its ubproject.toml.

‼️ Breaking Changes

  • MCP needs tools replacedget_data_for_single_need, get_schema_for_need_filter and query_needs are removed in favour of query_cypher and get_graph_schema. Update saved prompts, agent configurations and allowlists.

  • Cypher filter semantics — the VS Code needs-view filter boxes (and anywhere the previous pseudo-cypher dialect was used) now evaluate real openCypher: a missing field reads as null with three-valued logic (NOT (n.priority > 7) now drops needs without a priority), =~ is anchored full-string regex (was substring), upper() / lower() become toUpper() / toLower(), and the implicit one-hop l / o namespaces are removed (the error suggests the explicit MATCH (n)-[l:type]->(o) rewrite). The Python dialect and free-text search are unchanged. See the migration notes.

  • New warnings may appear — whole-project ubc check surfaces diagnostic families the old per-file mode never ran, and the new reference, toctree and substitution diagnostics also reach the editor — previously-clean CI runs may newly fail. Scope with --per-file, or suppress individual codes via the standard lint configuration. Info-only runs now exit 0 (use --deny info to fail on any finding).

  • View output is cappedneedlist / needtable / needflow default to :max_items: 100 with an explicit truncation notice, and default ordering is id-sorted for build-to-build reproducibility (upstream: document order).

  • ubc build list-documents orders by toctree by default and fails when the index cannot be built; --order path restores the previous pure-discovery listing.

  • One-time full re-index on upgrade — the cache format moved 6.15 → 6.40 across this release’s features and the config hash gained the new keys, so every project cold-rebuilds its index once. Self-healing, no action needed.

  • Driving Claude Code is ACP-only — selecting claude-code no longer opens a terminal with the claude CLI pre-typed; it runs in the Pharaoh Agent panel and requires ANTHROPIC_API_KEY. Declining the agent-skills install offer now genuinely cancels the action it gated (previously it carried on regardless).

🐛 Fixes

  • Crash fixes: a needextend argument of a lone " aborted the CLI; a malformed list-table / table could crash the language server and duplicate index entries; and pathological filter strings could overflow the stack — filter expressions are now bounded (16 KiB, 64 nesting levels).

  • :term: case-insensitive fallback is now deterministic when two glossary terms case-fold to the same string — resolved links no longer flip between builds.

  • Directives from enabled extension ports appear in autocomplete and hover (previously the parser knew video but completions did not).

  • ubc agent doctor and config-validate now reject a config that fails to load, in agreement with agent next, naming the offending line; doctor newly honours -c/--config and UBCODE_CONFIG_OVERRIDE.

  • Workflow editor: clicking a stage without a review skill no longer crashes the inspector, the graph follows the panel size, uses a proper layered layout (no overlapping labels), and no longer opens blank.

  • Pharaoh Gaps: a project whose ubproject.toml lives in a subfolder is no longer treated as greenfield, Set up project no longer tries to write to the filesystem root, and a need awaiting review reads “Missing review” instead of its own stage.

  • Onboarding hand-off prompts name the bundled, version-matched ubc (not whatever ubc is on PATH), and the detect-answers file is written outside the project and cleaned up afterwards.

  • Site Map rows no longer attract other extensions’ context buttons, and a collapsed hidden-toctree block in the preview can be expanded even with click-to-source enabled.

  • Codelinks: one-line markers terminated by a newline anchor to the comment start, so prose mentioning @author mid-comment no longer produces a bogus need.

  • Patched high- and moderate-severity advisories in the VS Code extension’s production dependencies (brace-expansion DoS, dompurify XSS, uuid bounds check).

0.31.0b1

Released:

16.07.2026

pre-release:

Three arcs this release: the Rendered preview hydrates cross-file links and need cards live from the index (and renders far more markup); the engine picks up saves, includes and imported content, with a wider diagnostic net; and Pharaoh — ubCode’s experimental agentic engineer — makes its debut.

✨ Preview

  • Cross-file hyperlinks (reference “hydration”)

    :ref: / {ref}, the :need: role family (directional and title <target> forms included), :doc: and :term: now render as working links in the Rendered preview once the background index has resolved the target: click-through opens the target document at the exact line, and placeholder chips upgrade to links as indexing completes. Resolved links show their target’s real title (explicit link text wins, then the resolved title, then the bare target; :need: references render as “Title (ID)”, matching sphinx-needs), and relative :doc: targets resolve Sphinx-faithfully from subdirectories. Unresolved (or !disabled) references keep the placeholder chip, and typing latency is unaffected — the preview only looks up what the index has already published; it never resolves.

  • Need cards

    Need directives (every type from needs.types) render as proper cards — type badge, title, ID, meta table and body — hydrated live from the index: field values include needextend modifications, outgoing links are clickable, and incoming “links back” rows show data absent from the source file. Cards show authored and extended state only, following the sphinx-needs show_in_layout taxonomy (config-default padding is skipped, so cards stay clean on hundred-field projects), and upgrade as indexing completes; Structural mode keeps the placeholder.

  • .. include:: is expanded in place

    Nested includes, live unsaved edits of the included file, the docutils slicing options (literal, start-line / end-line, start-after / end-before), section re-basing, and cycle / depth protection; a failed include shows an error chip carrying the docutils-shaped message. The included file becomes a tracked dependency of the index — editing it re-indexes every document that includes it — and missing files or failed slicing matches are diagnosed (directive.include_* codes). Not yet expanded: MyST {include} and the remaining docutils options (parser, code, …), each diagnosed as unsupported; targets and needs in an included file still attribute to the fragment file.

  • Document state: default role, custom roles and highlight language

    .. default-role::, doc-local .. role:: definitions and .. highlight:: now take effect instead of being inert: bare interpreted text (`` text ) renders as docutils' ``title-reference — following an active default-role — instead of raising a bogus warning, custom roles resolve within the document, and highlight sets the language of subsequent literal blocks (a muted chip marks each state change). New [parse] keys — Sphinx confval equivalents — seed the initial state: default_role and highlight_language (an unknown configured role is diagnosed as config.unknown_default_role), plus rst_prolog / rst_epilog to prepend / append source to every RST document — as in Sphinx, prologue state applies to the whole document, and an .. include:: inside it works (substitution definitions do not yet expand). See Parsing.

  • Code blocks render with syntax highlighting

    The code-block, sourcecode and code directives render as real literal blocks (previously generic placeholders) with :caption:, :name: and :class: support, coloured by bundled client-side highlighting that follows the editor’s light / dark theme. The language comes from the directive argument, falling back to the current highlight state or [parse] highlight_language.

  • Much wider markup coverage

    Newly rendered: the docutils text roles (:title-reference: and friends), deterministic :pep: / :rfc: link roles, the Sphinx UI and styled-literal roles (:kbd:, :menuselection:, :file:, …), the sphinx-needs :variant: role, version-change directives (versionadded / versionchanged / deprecated), structural block directives (topic, sidebar, rubric, …), centered and hlist, diagram directives with file arguments, image / figure parity, admonitions including seealso and :collapsible:, and generic need-type rendering. Unhandled roles now at least visualise their name and content. The new Authoring reference documents exactly what renders — and where the preview deliberately differs from Sphinx.

  • Diagram captions, alignment and sizing

    The mermaid, uml and plantuml directives’ :caption: and :align: options are now respected — a caption wraps the diagram in a figure — and :width: / :height: size it (a bare number means pixels; a small deliberate extension over upstream sphinxcontrib-mermaid so all three directives size consistently). Diagrams without these options render exactly as before.

✨ Indexing & diagnostics

  • Saving now refreshes cross-file features by default

    [server] index_on_save now defaults to true, made safe by a new trailing debounce: burst saves coalesce into one indexing pass after a quiet window ([server] index_debounce_ms, default 500; 0 = immediate). Diagnostics, preview hydration and need cards heal on save out of the box; set index_on_save = false to restore the old behaviour.

  • if directive for conditional content (Sphinx-Needs 8.2 parity)

    The Sphinx-Needs .. if:: / {if} directive is now supported: its argument is a filter expression evaluated against the build’s variant data (the var.* namespace from needs_variant_data). A truthy condition includes the body — needs inside are collected and indexed as if unwrapped; a falsy condition excludes it entirely — needs are not collected and targets do not resolve, matching Sphinx-Needs. An expression that cannot be evaluated is reported as if.invalid_expression and the body is excluded.

    In the editor, a falsy if block renders in the preview as a collapsed, greyed block labelled with its condition, and the inactive source region is faded (like disabled code behind an #if in a C editor) — conditional content stays visible without cluttering the active view. See the if directive.

  • Real-time validation of need option values as you edit

    Need option values are now checked against their schema while you type, publishing editor squiggles for the open document — no full project build required — in both reStructuredText and MyST Markdown (previously these issues surfaced only after a full index build, in the diagnostics panel). Three codes are published, each suppressible via the lint configuration: needs.invalid_field_value (enum / const, string length, numeric bounds, array constraints), needs.invalid_link_value (link-ID length), and needs.dynamic_functions (a [[...]] value that does not look like a dynamic-function call). The checks are deliberately lightweight — regex pattern / format validation and dynamic-function values are left to the full build — so they stay cheap on every keystroke.

  • Imported need content is now parsed

    The content of needs pulled in via needimport is markup-parsed in the importing document’s format: need parts become addressable, :need: references join the link graph (including backlinks), and markup problems surface as diagnostics anchored at the needimport directive, prefixed with the need’s ID. Imported content parses context-free — without the host document’s substitutions or relative paths — a deliberate, documented divergence from sphinx-needs’ accidental host-context leakage; nested generative directives are diagnosed (needs.import.nested_generative), never executed.

  • Markdown (MyST) documents contribute to the project index

    Markdown / MyST documents now contribute their structure (titles, headings, targets, footnote definitions) to the project index, as reStructuredText always has — cross-references into MyST documents resolve (including from reStructuredText, and in the preview links above), and Markdown titles surface in language-server features.

  • New markup diagnostics

    All surfacing as editor squiggles (ubcode-syntax source), in ubc check and in the build index log, governed by the standard lint configuration:

    • invalid directive option values and choices, diagram content-plus-file conflicts, and non-consecutive Markdown heading levels;

    • directives missing a required argument (reStructuredText and MyST);

    • invalid :variant: / :pep: / :rfc: role content;

    • directive-name collisions between needs.types and extend_directives in the configuration.

🤖 Pharaoh — the agentic engineer (experimental)

This release debuts Pharaoh, ubCode’s agentic engineer: describe your engineering process once — the stages a requirement passes through, and the evidence each stage needs — and from then on AI does the writing while the engine does the judging: what is done, what is missing, what to do next. Experimental (ubc agent is still hidden from ubc --help) and may change between releases; see the Pharaoh documentation for the full guide.

  • Describe your process; the engine judges

    A new [workflow] configuration section (Workflow) declares your process as stages that produce need types, depend on each other, and carry gates (trace links, code coverage, lifecycle, review). On top of it: ubc agent next names the single next thing to build (make for your requirements), gaps lists every unmet obligation, status reports each stage done / ready / blocked, and release-check is the combined final gate — all projections of one deterministic evaluation, so they can never disagree.

  • Onboarding, greenfield and brownfield

    ubc agent install scaffolds a workflow from a profile (default: a V-model) plus its AI-asset bundle of skills and agent definitions; install --detect onboards an existing project by deriving a drivable [workflow] from the observed link graph and schemas, raising only what it cannot infer as a few evidence-backed questions (--plan previews, --answers applies); ubc agent doctor pre-flights the setup.

  • Quality Analysis — independent review of need substance

    The graph judges structure; Quality Analysis judges substance — and the AI never grades its own homework. A new [quality] section (Quality Analysis) defines criteria packs (per-axis rubrics as TOML data) and per-axis floors: an LLM measures each need, the engine judges pass / fail deterministically at read time, and the IDE explains the result. Verdicts live under .pharaoh/verdicts/ and fingerprint both the need’s one-hop content and the criteria, reading as outdated when either drifts. The review-brief, verdict-submit and verdict-check verbs gate substance fail-closed (also folded into release-check --with-verdicts); in VS Code, Run QA drives the review through the editor’s language-model access (ubCode never talks to an LLM provider itself), with a results panel and live CodeLens badges.

  • The VS Code cockpit

    Pharaoh Workflows and Gaps Overview panels, a workflow-aware needs graph with gap rings and a parent / child depth control, a read-only workflow-editor graph, per-need CodeLenses with gap diagnostics in the Problems panel, and the Drive / Accept / Tailor commands — hand the next step to your AI agent, commit only the authored artefacts, or derive a [workflow] proposal from existing types and links. Without a [workflow] section none of this appears — the agent surface stays silent until you opt in.

  • The chat participant is now @pharaoh

    Renamed from @ubcode (kept as an alias; chat history survives), with high-level intents captured via /pharaoh-intent. The participant — and every driving skill — now runs the extension’s bundled, version-matched ubc binary: no PATH setup, no mismatched installs.

👌 Improvements

  • Language-server request latency

    Requests no longer deserialize the needs / domain / diagnostics indexes from disk — they reuse the in-memory snapshot the background indexer already published (roughly 66 ms → sub-millisecond per request at 10,000 needs), and the indexer reuses its own indexes across passes, so incremental network_back validation now engages between background runs. External CLI builds are still adopted automatically.

  • Faster schema validation: needs-network schema validators are now precompiled once per pass, with a hub-graph fallback for highly connected projects.

  • Faster index builds: the config-derived directive-specification table is built once per pass and shared, instead of rebuilt per file — roughly 0.6–0.8 s of cold-build wall time on a 5,000-file corpus.

  • Markdown (MyST) inline constructs now carry precise source ranges, improving diagnostic and navigation targets.

  • New “Authoring” documentation section: a reference for what the preview renders — directives, roles, needs and diagrams, Markdown — with an explicit differences-from-Sphinx page (see Authoring).

  • The editor-title preview icon now carries a small magnifier badge, so it is distinguishable from the built-in Markdown preview icon.

  • Hovering a :variant: role value in reStructuredText now shows its resolved variant data, and the docutils generic text roles are offered in role-name completion.

  • The PlantUML-to-Mermaid preview conversion handles multi-line and rectangle / hexagon sequence notes, activation-shortcut colours and group end variants, with hardened diagram detection.

♻️ Changes

  • Preview always renders via the unified AST; new Rendered / Structural modes

    The preview now always lowers the parsed document to the unified AST and renders from it — the per-format concrete-syntax-tree path is retired, along with the internal server.use_ast_preview flag (never part of a release). The old rich/plain toggle becomes two modes, switchable live from the preview toolbar:

    • Rendered (the default) — every construct renders as its semantic HTML shape (headings, admonitions, images, diagrams, tables, …).

    • Structural — “show me what was parsed”: every directive and role renders as a uniform placeholder (name, arguments, options, body), identical for reStructuredText and MyST.

    The VS Code setting ubcode.preview.experimentalRendering (boolean) is renamed to ubcode.preview.mode (rendered | structural), which seeds the panel’s initial mode.

  • Need extraction is sourced from the unified document AST

    Need directives (fields, links, parts, content links, diagnostics) are now extracted from the same unified AST the preview renders from, rather than a separate concrete-syntax-tree walk — an internal unification with no intended behaviour change, apart from the MyST body-role fix below.

‼️ Breaking Changes

  • One-time full re-index on upgrade

    The cache format version moved 6.10 → 6.15 (imported-content parsing, glossary display text, :doc: / :term: site collection, the state-directive diagnostics, include dependency edges) and the config hash gained new inputs ([server] index_on_save / index_debounce_ms, [parse] default_role / highlight_language / rst_prolog / rst_epilog), so every project cold-rebuilds its index once after upgrading. Self-healing — no action needed.

  • New warnings may appear

    ubc check / ubc build index (and the editor) now report the markup-semantics, required-argument and role-resolution diagnostics above, the needs.import.* codes, the interpreted-text role codes below, and config.unknown_default_role — CI gating on warning counts may newly fail. Suppress individual codes via the standard lint configuration.

  • New include warnings may appear

    Projects with broken .. include:: paths — or jinja-templated ones (e.g. {{ build_root }}/…), which ubCode cannot expand yet — now get directive.include_not_found warnings (~150 on one large real-world corpus, from templated paths alone). Suppress the code until jinja support lands.

  • Diagnostic changes for interpreted text

    The inline.role_no_name warning is retired — bare `` text `` is legal docutils — so suppressions keyed on it are dead configuration. In exchange, directive.unknown_role, directive.invalid_role and directive.role_redefinition are diagnosed (docutils reports these as errors; on by default).

  • Anchors unified to exact docutils rules

    Rendered previews and the objects inventory derive every anchor through one docutils-faithful make_id (differentially fuzzed against real docutils). Anchors that diverged from sphinx-build output move to the Sphinx-identical form — a parity upgrade, but external deep links to the old anchors need updating.

  • needextend application order now matches sphinx-needs

    When several needextend directives modify the same field of the same need, they apply sorted by (docname, lineno) — the sphinx-needs contract, verified against a real sphinx-needs 8.2.0 build — instead of file-path order. Projects whose path order and docname order differ (e.g. x.rst vs x-y.rst) may see different final values; the new values are the ones sphinx-needs produces.

  • Background indexing now runs on save by default — set [server] index_on_save = false to restore the previous behaviour (see the feature entry above).

  • Editor diagnostic source renamed: ubcode-rst-lintubcode-syntax — the source now covers Markdown too. Any client-side filters keyed on the old source string must be updated.

  • Needs inside a falsy .. if:: block are now excluded from the index: previously the (unknown) directive was a no-op, so such needs were still collected.

  • Pharaoh state directory: agent state now lives in .pharaoh/ (a .ubc/ from earlier development builds is ignored) — verdicts re-derive on the next review, the install manifest on the next ubc agent install.

🐛 Fixes

  • The CommonMark parser no longer panics on a no-break space (U+00A0) near heading / paragraph boundaries.

  • Image and figure src paths now resolve correctly in the Markdown (MyST) preview.

  • MyST need bodies now collect their {need} and {need_part} roles

    A {need} / {need_part} role inside the body of a MyST need directive is now collected (as a content link / need part), matching reStructuredText need bodies. Previously such roles were silently ignored, so content links and parts were missing from the extracted need (and part-dependent diagnostics such as duplicate-part warnings could not fire).

  • MyST diagram directives now render in the Markdown preview.

  • The MCP stdio server no longer drops connections intermittently on Linux.

  • Language-server edge-case fixes: float enum values in need-field validation, hover ordering, and schema key handling.

0.30.3

Released:

01.07.2026

✨ New Features

  • PlantUML diagrams in the rich preview

    The sphinxcontrib-plantuml uml directive (and its plantuml alias) now renders as a diagram in the VS Code rich preview, converted best-effort to Mermaid and drawn client-side — no PlantUML toolchain or server required. When a diagram can’t be converted cleanly, the preview falls back to showing the directive source rather than a blank box or a parse error. Coverage spans sequence, class, component/description, state, and activity diagrams.

    This is built on a brand-new Rust-based PlantUML parser, which lays the groundwork for richer features in the future — for example, validating class diagrams against the source code they describe (via the codelinks features).

  • network_back schema key

    Schemas can now validate a need’s incoming links via a new network_back key, complementing network (outgoing links). This mirrors sphinx-needs#1731, available in the next Sphinx-Needs release, bringing the two implementations to parity.

  • Source-code tracing: back-attach URLs onto referenced needs

    ubc build now honours @need-ids: reference markers in source code: the marker’s URL is written onto the already-existing referenced need, under a configurable field (ref_url_field, default code_url). This complements the existing markers that define needs from code, and lets you keep, for example, implementation and test links in separate fields.

  • Go-to-definition for codelinks need IDs

    Pressing F12 / Go to Definition on an outgoing linked need ID inside a @need marker now jumps to that need’s definition.

👌 Improvements

  • Schema validation diagnostics now align more closely with Sphinx-Needs: all network-local validation errors are surfaced (previously some were hidden), message text matches Sphinx-Needs, invalid or circular $refs are reported, the id[index] of the failing item is included in the diagnostic, and runtime-injected core fields (docname / is_external / is_import) resolve correctly during validation.

  • Faster reStructuredText parsing through a series of inline-processing optimisations.

🐛 Fixes

  • reStructuredText parsing now matches docutils more closely: codepoint-correct backslash-escape handling, Unicode-aware simple names, table character-width semantics, and attribution matching.

  • The Markdown (MyST) parser no longer panics on a lone carriage return inside directive options.

0.30.2

Released:

23.06.2026

0.30.2 is the first stable release in the 0.30 series. It builds on the 0.30.0b1 and 0.30.1b1 pre-releases, so in addition to the changes listed below it includes everything from those, most notably:

  • the native Rust ubc CLI and language server, with the indexing pipeline and reStructuredText IDE features now powered by Rust (0.30.0b1, 0.30.1b1);

  • Markdown (MyST) authoring support, with the [parse.parsers.<name>] parser / file-routing configuration (0.30.0b1);

  • HTML report templates, the ubc report command, and the VS Code Reports view (0.30.0b1);

  • command-line need querying via ubc query filter (0.30.0b1);

  • build-variant data in filter expressions and field values via needs.variant_data and the var.* namespace (0.30.0b1);

  • the links_from_content() dynamic function and project flavors for ubc quickstart (--flavor) (0.30.1b1).

See the pre-release entries below for the full details.

✨ New Features

  • Markdown (MyST) language-server support

    Building on the Markdown (MyST) authoring support added in 0.30.0b1, the language server now provides in-editor features for Markdown files that were previously available only for reStructuredText:

    • directive name and option completion,

    • go-to-definition and find-references for need link option values,

    • semantic highlighting for block constructs and option keys.

  • MCP server in the ubc CLI

    The Model Context Protocol server now runs from the single native ubc CLI via ubc serve mcp, alongside the language server via ubc serve lsp, with license checking. The VS Code extension launches both servers from its bundled ubc CLI.

  • Bundled ubc CLI on the integrated-terminal PATH

    The VS Code extension now adds its bundled ubc CLI to the integrated terminal’s PATH, so you can run ubc commands in the terminal without installing the CLI separately.

🐛 Fixes

  • The language server no longer re-logs the document route on every keystroke, reducing noise in the language-server output.

0.30.1b1

Released:

17.06.2026

pre-release:

✨ New Features

  • Native Rust language server

    The VS Code extension now launches a native Rust binary instead of the previously bundled Python language server. Dropping the bundled Python runtime makes the extension smaller to install and quicker to respond.

    IDE behaviour should match the previous implementation, but please report any regressions you notice.

  • links_from_content() dynamic function

    A new built-in dynamic function, links_from_content(), returns the needs referenced via :need: roles in a need’s own content, for use in a link field:

    .. spec:: My specification
       :id: SPEC_001
       :links: [[links_from_content()]]
    
       This specification realises :need:`REQ_001`.
    
  • Project flavors for ubc quickstart

    ubc quickstart gained a --flavor option to choose which example project is scaffolded:

    • minimal (default) — a minimal reStructuredText project,

    • full — a feature tour with RST and Markdown, variants, links, and reports,

    • markdown — a minimal Markdown (MyST) project,

    • variants — a build-variant (“150% model”) project.

👌 Improvements

  • In the VS Code Reports view, the report Open in Browser action is now a primary inline button (shown alongside Edit and Generate & Preview), rather than being hidden in the right-click menu. This is the action that renders a report with its <script> blocks and external CSS/JS frameworks as a standalone, shareable file.

🐛 Fixes

These fix the Markdown (MyST) authoring support introduced in 0.30.0b1.

  • Need directives without a title (and other directives with optional arguments, such as code-block and needuml) in Markdown (MyST) files no longer emit a spurious directive.missing_argument warning, matching reStructuredText behaviour.

  • The myst parser flavour now enables no optional Markdown extensions by default, matching MyST-Parser. Previously deflist, dollarmath, colon_fence, and fieldlist were on by default; enable the ones you need explicitly via the parser extensions setting.

0.30.0b1

Released:

12.06.2026

pre-release:

✨ New Features

  • Markdown (MyST) authoring support

    Projects can now define needs in Markdown (MyST) files alongside reStructuredText. The new [parse.parsers.<name>] configuration tables declare the parsers a project uses, select the files each parser owns, and route every discovered file to the right one:

    [parse.parsers.rst]
    
    [parse.parsers.md]
    flavour = "myst"
    include = ["docs/**/*.md"]
    

    Need directives in Markdown files are indexed, validated, and queryable just like their reStructuredText counterparts. Projects that declare no parsers keep the existing behaviour: every file discovered via [source] is parsed as reStructuredText. See parsers and file routing for details.

    Note that language-server features for Markdown files in the VS Code extension (such as in-editor diagnostics, as already available for reStructuredText) are not yet implemented, but are planned for a future release.

    ubc build list-documents also gained a --parser flag that shows which parser each source document is routed to.

  • HTML report templates

    ubCode can now render user-authored Jinja templates (*.html.j2) against the project’s needs index, producing a single self-contained HTML file:

    • The new ubc report command renders a template by name (or lists the available templates with --list).

    • The new [reports] configuration section sets the templates directory and an output size limit.

    • In VS Code, a new Reports view in the ubCode sidebar lists the project’s templates, with in-editor preview and Open in Browser actions; render failures are reported in the Problems panel.

    • ubc quickstart now scaffolds a runnable starter template demonstrating grouped tables and an inline SVG chart.

    Reports view and in-editor report preview in VS Code

    The Reports view and in-editor report preview in VS Code.

    See reports for more details.

  • Query needs from the command line

    The new ubc query filter command filters the needs of a project using Python-style filter expressions, printing the results as a human-readable table or as JSON (--format json) that pipes cleanly to tools like jq:

    $ ubc query filter 'type == "req" and status == "open"' --field id --field title
    

    The project is automatically (and incrementally) re-indexed before querying, so results are always up to date; use --no-cache to bypass the on-disk cache entirely.

  • Variant data for build-variant-aware projects

    Filter expressions can now reference external build-variant data via the new needs.variant_data / needs.variant_data_file configuration and the var.* namespace, e.g. var.platform == "windows" or "arm" in var.archs. Need field and link values can also pull values directly from the variant data using the new <{ var.* }> reference syntax:

    .. req:: Example
       :id: REQ_001
       :platform: <{ var.platform }>
    

    See variant builds and variant data for more details.

    These features mirror the upcoming additions to sphinx-needs (currently on its master branch, to be released soon). The if directive is not yet handled, but support is hoped to land soon.

    Relatedly, ubc diff gained a --config option for comparing a project against itself under a configuration override, e.g. ubc diff -c "needs.variant_data_file = 'variants2.json'".

  • Native Rust ubc CLI

    The standalone ubc binary is now the native Rust implementation of the CLI, replacing the previous Python-based bundle, with faster startup and indexing. The command surface, output, and exit codes match the Python implementation.

👌 Improvements

  • Indexing pipeline moved to Rust

    Project indexing — as used by ubc build, ubc check, ubc diff, ubc schema validate, and ubc query — now runs the Rust pipeline end-to-end, improving performance. The legacy --parallel / --no-parallel and --force-parallel options are deprecated no-ops: they are still accepted (with a deprecation warning) but hidden from help output.

  • IDE reStructuredText features now powered by the Rust parser

    Formatting, HTML preview, completions, hover, definitions, references, and the document outline in the language server are now all backed by the Rust RST parser. The document outline (and editor breadcrumbs) now nest sections hierarchically.

  • ubc build needs gained a --pretty flag for indented, human-readable JSON output.

  • Unified AST for RST and Markdown/MyST (ubc_ast)

    A new ubc_ast crate introduces a format-agnostic intermediate representation shared by the RST and Markdown/MyST parsers. Each source file’s CST is lowered to a syntax_tree::Tree — the same arena-allocated, anymap-per-node structure used throughout the rest of the codebase — using a 90-type vocabulary derived from the docutils Generic DTD, covering all structural, body, body-subelement, and inline elements (admonitions, figures, sidebars, tables, and everything in between), plus format-specific extensions (YAML front matter, MyST block break, GFM strikethrough, hard and soft line breaks, and roles). Node dispatch in the display and writer code uses a sorted (TypeId, fn) table binary-searched per node, matching the pattern already established in the RST writer. This representation will power future language-server features such as cross-format structural navigation and traceability.

🐛 Fixes

  • Fixed go-to-symbol, hover, and selection for content nested inside RST sections; a section now spans its whole body rather than just its title line.

  • Find References on a need part (e.g. REQ_123.x) now returns only that part’s references, not all references to the base need.

  • Fixed malformed HTML in the license-restricted preview banner.

  • Malformed inline markup that exceeds the regex backtrack limit now emits a diagnostic instead of failing the parse.

  • Source files are now sorted before indexing, so duplicate-ID resolution and the resulting diagnostics are deterministic across runs.

0.29.3

Released:

20.05.2026

This release promotes the 0.29.x pre-release series to a stable release. See the pre-release entries below for details:

🐛 Fixes

  • Stabilized changelog anchors for pre-release versions in the documentation.

0.29.2b1

Released:

13.05.2026

pre-release:

✨ New Features

  • Free-text filter in the Needs Index view

    The VS Code Needs Index now offers a free text filter type that searches across the textual fields id, title, and content of each need in one go.

    Free-text filter in the Needs Index view

👌 Improvements

  • Need content available via the MCP query_needs tool

    The MCP server’s query_needs tool now exposes the content field alongside the other need attributes, matching the get_data_for_single_need endpoint and the build artefacts. AI assistants and other MCP clients can retrieve and filter on the directive body text directly, without a follow-up per-need lookup.

  • Opt out of need content in build artefacts

    The ubc build needs command gained a --no-content / --content toggle controlling whether the directive body text (the content field introduced in 0.29.1b1) is emitted into the build artefacts. Use --no-content to keep generated JSON / Parquet output compact when downstream tooling does not consume the body text.

0.29.1b1

Released:

30.04.2026

pre-release:

✨ New Features

  • content field on need items

    Need items now carry an optional content field that stores the raw body text of the directive. Content is included in JSON and Parquet exports, queryable in filter expressions (e.g. "keyword" in content), returned by the MCP single-need endpoint, and checked in ubc diff. Content is preserved through directive, import, and external need sources.

  • follow_links configuration for codelinks source discovery

    A new follow_links option in [codelinks.projects.*.source_discover] controls whether symbolic links are followed during codelinks file discovery. See codelinks configuration for more details.

👌 Improvements

  • Aligned codelinks file discovery behaviour with sphinx-codelinks, improving consistency between the IDE tooling and the Sphinx extension. The C/C++ recognised file extensions were updated (now .c, .ci, .cpp, .cc, .cxx, .h, .hpp, .hxx, .hh, .ihl).

🐛 Fixes

  • Fixed mermaid diagram labels in the VS Code RST preview being clipped mid-word.

0.29.0b1

Released:

23.04.2026

pre-release:

✨ New Features

  • Source code traceability with codelinks

    ubCode now supports tracing requirements directly in source code comments, creating a live bidirectional link between documentation and code. This implements the sphinx-codelinks marker format natively in the IDE. Embed standardised markers in C++, Python, Rust, C#, or YAML comments and ubCode extracts them into need objects automatically.

    One-line need definitions let you create a new need from a single comment:

    # @Function Bar, IMPL_4, impl, [SPEC_1]
    def bar():
        ...
    

    Note

    Need-ID references (@need-ids:) are not yet supported and are planned for a future release.

    The .. src-trace:: RST directive includes traced needs in your documentation, scoped by project, file, or directory.

    IDE features delivered through the language server:

    • Real-time diagnostics for malformed one-line markers (source: ubcode-codelinks; codes include too_few_fields, too_many_fields, missing_square_brackets, etc.)

    • Hover on markers shows a rich card with the need’s type, ID, title, metadata fields, and link targets

    • Find References from a source code marker navigates to all RST documents that backlink via field values or :need: roles

    • Autocomplete for the :project: option in .. src-trace:: directives, populated from [codelinks.projects.*] keys in ubproject.toml

    Parsing is implemented in Rust (via tree-sitter) and runs incrementally — only changed files are re-parsed, keeping the feedback loop fast.

    See Tracing source code with Codelinks for the full usage guide and Codelinks (source code tracing) for the configuration reference.

  • ubc build list-documents --codelinks CLI option

    The ubc build list-documents command now supports listing files from configured codelinks projects: --codelinks / --no-codelinks to include codelinks source files, --codelinks-project <name> to filter to a specific project, and --source-documents / --no-source-documents to toggle RST/MD source documents. These can be combined, e.g. --codelinks --no-source-documents to list only codelinks files.

  • Configuration redirect with ubproject.redirect.toml

    A new redirect file mechanism lets ubCode find the ubproject.toml for files that live outside the documentation folder (e.g. source code files traced via codelinks). Place a ubproject.redirect.toml containing path = "../docs" in your source directory and ubCode follows the redirect during its configuration file search. Circular redirects are detected and handled gracefully.

    See Configuration redirect with ubproject.redirect.toml for details.

👌 Improvements

  • Labels on diagnostic source locations

    Diagnostics in the ubCode Issues panel now annotate each source location with a descriptive label (e.g. needimport-source, external-source), making it easier to understand the role of each location when a diagnostic spans multiple files, such as link constraint violations.

  • Expanded and reorganised the user documentation, including new configuration examples and a codelinks usage guide.

0.28.2

Released:

15.04.2026

✨ New Features

  • Pin project in VS Code views

    A new ubcode.views.pinnedProject VS Code setting lets you lock all views (Needs Index, Diagnostics, Needs JSON, Std Domain, Needs graph) to a specific ubproject.toml, so they no longer switch context when the active editor changes. Pin and Unpin buttons are available in the tree view toolbar and context menu. Path variables (${workspaceFolder}, ${userHome}, etc.) are also supported.

👌 Improvements

  • Improved diagnostic locations for needextend and link conditions

    Validation diagnostics now include the source locations of needextend directives that modified a need, in addition to the original need definition. Link condition diagnostics likewise show the location of the target need (and any needextend on it). This makes it much easier to trace the root cause of validation failures.

  • Smarter configuration cache invalidation

    The configuration cache now tracks modification times of external files referenced by ubproject.toml (e.g. schema JSON files), not just the config file itself. Changes to those files now correctly trigger a re-index.

  • More flexible MCP tool parameter names

    The MCP server’s query_needs_advanced and get_single_need tools now accept common aliases for their input fields (e.g. select for fields, need_id for id), and sort_direction accepts case-insensitive variants. This improves robustness when AI assistants call the MCP tools.

🐛 Fixes

  • Fixed RuntimeError: Already borrowed crashes in the language server, caused by concurrent LSP requests.

0.28.1

Released:

01.04.2026

👌 Improvements

  • Natural sort order in the Needs Index tree view

    The Needs Index tree view now sorts need IDs, group keys, and link types in natural sort order, so REQ_2 appears before REQ_10 instead of after it. Link targets within each type are also deduplicated and naturally sorted.

🐛 Fixes

  • Fixed the @ubcode chat participant losing conversation context (“amnesia”) when it invoked tools during a chat session.

0.28.0

Released:

31.03.2026

✨ New Features

  • Chat participant

    The new @ubcode chat participant integrates with GitHub Copilot Chat to give you an AI assistant with deep knowledge of Sphinx-Needs and ubCode. Type @ubcode in the Copilot Chat panel followed by your question and the participant automatically fetches the most relevant documentation to generate a focused answer.

    Example of the chat participant in action

    Example of the chat participant in action, called from the VS Code Chat panel.

    For more information, see the chat participant documentation.

0.27.0

Released:

19.03.2026

✨ New Features

  • Conditional link assessment (sphinx-needs v8 compatibility)

    ubCode now supports inline conditions on need links, matching the conditional link assessment feature introduced in sphinx-needs 8.0.0.

    Append a filter expression in square brackets after a target ID to assert that the linked need satisfies a condition:

    .. spec:: My Specification
       :links:
         REQ_001[status=="open"],
         REQ_002[version>=3]
    

    Each condition is evaluated against the target need’s fields at index time. Links without conditions continue to work exactly as before.

    When the condition contains square brackets (e.g. for list indexing), use multiple opening brackets — the parser matches N opening [ with N closing ]:

    .. spec:: My Specification
       :links: REQ_001[["important" in tags]]
    

    Two new diagnostic codes are emitted:

    • needs.link_condition_failed — the condition evaluated to false against the target need.

    • needs.link_condition_invalid — the condition has invalid syntax and could not be parsed.

    Condition evaluation is incremental: when a target need changes (e.g. its status field is updated), all needs linking to it with conditions are automatically re-validated.

    A new per-link-type parse_conditions option controls whether bracket syntax is interpreted as a condition expression or treated as literal ID text (defaults to true):

    [needs.links.raw_links]
    parse_conditions = false
    

🐛 Fixes

  • Fixed Windows configuration directory path to match pre v0.22.0b1 behavior

    The Rust-based license checker introduced in v0.22.0b1 changed the ubCode config directory on Windows, which could break license activation. The pre v0.22.0b1 behavior is now restored., so the config file is expected at C:\Users\<username>\AppData\Local\useblocks\ubcode\ubcode.toml again. See the ublicense documentation for more details: Commercial.

0.26.0

Released:

16.03.2026

✨ New Features

  • Resolution of simple dynamic functions ([[...]] syntax)

    ubCode now resolves some built-in dynamic functions ([[...]] syntax) from sphinx-needs. If your documentation already uses dynamic functions, they were previously parsed and stored on need items but left unresolved — they will now be evaluated during indexing. Three built-in functions are supported in this initial release:

    • echo("text") — returns the given string unchanged

    • test(*args, **kwargs) — returns a debug string with the need ID and arguments

    • copy("field") — copies a field value from the current need (also supports lower and upper kwargs)

    For example:

    .. req:: My requirement
       :id: REQ_001
       :status: [[copy("priority")]]
    

    Dynamic functions are resolved alongside variant functions in the same resolution pass. Parse and execution errors are surfaced as needs.dynamic_function diagnostics.

    Dynamic function parsing is enabled by default and can be controlled via needs.parse_dynamic_functions globally, or overridden per-field or per-link. Variant function parsing (parse_variants) is also now configurable per-link. For example:

    [needs]
    parse_dynamic_functions = false  # disable globally
    
    [needs.fields.my_field]
    parse_dynamic_functions = true   # re-enable for this field
    
    [needs.links.implements]
    incoming = "is implemented by"
    outgoing = "implements"
    parse_dynamic_functions = true   # re-enable for this link
    parse_variants = true            # also enable variant parsing
    

    The LSP provides real-time syntax checking for dynamic function calls.

  • Added core need fields: layout, style, collapse, hide

    Added support for the layout, style, collapse, and hide core need fields, aligning with sphinx-needs’ presentation options. These fields are now recognised during indexing, validation, and autocompletion, and will appear in the VS Code Needs Index tree view, ubc build needs JSON output, MCP queries, and other need-aware features.

  • ubc agent-skill CLI command

    New command that auto-generates a Markdown reference document (SKILLS.md) describing the full CLI for AI agents and copilots, aligned with the agentskills.io specification.

    ubc agent-skill          # print to stdout
    ubc agent-skill -o SKILLS.md  # write to file
    

🐛 Fixes

  • Fixed TLS “UnknownIssuer” certificate errors when using the new Rust-based license checker (introduced in v0.22.0b1) behind corporate proxies or with custom enterprise CAs. License validation now delegates certificate verification to the operating system, matching the previous behavior.

  • Fixed ubc CLI failures on Windows when the installation path was deeply nested, caused by exceeding the Windows 260-character path limit (MAX_PATH). This could manifest as “file not found” or “path too long” errors when running CLI commands.

0.25.0

Released:

10.03.2026

✨ New Features

  • Mermaid diagram rendering in the RST preview

    The RST preview panel now renders .. mermaid:: directives as live diagrams, building on the image and figure rendering introduced in 0.23.0. Rendering is highly responsive — diagrams update instantly as you type, without flickering or disappearing while you edit other parts of the document. Diagrams also adapt automatically to your VS Code color theme.

    As with image preview, this feature requires ubcode.preview.experimentalRendering to be enabled in your VS Code settings (or toggled via the preview toolbar button).

    Caution

    External file references (e.g. .. mermaid:: path/to/file.mmd) are not yet supported; only inline diagram source is rendered. External file support is intended for a future improvement.

👌 Improvements

  • Significantly reduced needs index size

    The needs index now deduplicates field values that match their schema defaults, dramatically shrinking cached index files and speeding up load times. As a reference point, a project with ~40,000 needs and ~120 custom fields sees its cached index shrink from 109 MB to 31 MB and loads ~5x faster.

    This means noticeably faster startup for VS Code features that depend on the index — particularly the Needs Index tree view and the Need graph view — as well as faster incremental builds, CLI commands, and MCP queries.

0.24.1

Released:

04.03.2026

✨ New Features

  • Config override support in the VS Code extension

    The VS Code extension now exposes two new settings, ubcode.server.configOverride and ubcode.mcp.configOverride, that let you override any ubproject.toml value directly from your editor settings without modifying the project file.

    Each setting accepts a JSON object whose keys and values mirror the TOML configuration. The overrides are serialized to TOML and passed to the language server (via a -c CLI flag) and the MCP server (via the UBCODE_CONFIG_OVERRIDE environment variable), respectively.

    A prime use case is controlling variant resolution (added in 0.24.0) on the fly. For example, to change the active build_tags without editing ubproject.toml:

    {
      "ubcode.server.configOverride": {
        "build_tags": ["html", "draft"]
      }
    }
    

    This makes it easy to switch between build variants while developing, and to preview how different tag combinations affect your requirements. Changes to either setting take effect immediately: the language server restarts and the MCP server definition is refreshed automatically.

0.24.0

Released:

03.03.2026

✨ New Features

  • Variant resolution for needs

    Need fields and links can now contain variant functions using the <<...>> syntax, allowing conditional values that resolve based on configured variants and filter data. This implements the Sphinx-Needs variant functions feature, bringing ubCode closer to full feature parity with sphinx-needs. See Supported toolchain for the full list of supported configurations, and Variants for configuration details.

    Three expression forms are supported:

    • Named variants (<<name: value_if_match, fallback>>): name is looked up in the [needs.variants] configuration mapping.

    • Bracketed expressions (<<[expr]: value_if_match, fallback>>): expr is evaluated directly as a filter expression.

    • Fallback values: the last comma-separated value is used when no expression matches.

    For example:

    .. req:: My requirement
       :id: REQ_001
       :status: <<is_open: active, inactive>>
    

    Variant resolution runs after needextend processing, so extended field values are available to variant expressions. Resolved values are fully validated downstream. Parse and evaluation errors are surfaced as needs.variant diagnostics.

    Variant syntax is only parsed for fields that opt in: either by setting parse_variants = true in the field’s needs.fields schema (sphinx-needs v7+), or by listing the field name in variant_options.

    Incremental builds only re-resolve needs that have changed, and a pre-parsed expression cache avoids redundant work during parallel resolution.

  • build_tags configuration attribute

    A new build_tags list can be set in ubproject.toml to declare the active build tags for a project. This replicates the Sphinx tags feature, making the same set of tags available to variant filter expressions as a list variable and enabling build-target-conditional field values.

    For example, given the configuration:

    build_tags = ["html"]
    
    [needs.variants]
    is_html = "'html' in build_tags"
    

    a need with :status: <<is_html: web_only, general>> will resolve to web_only when html is in build_tags, or general otherwise.

    Tags can also be overridden from the CLI using the -c option, without modifying ubproject.toml:

    ubc build index -c "build_tags = ['html', 'draft']"
    

    or via the UBCODE_CONFIG_OVERRIDE environment variable.

    See Top-level options for full documentation.

0.23.0

Released:

26.02.2026

✨ New Features

  • Experimental image preview rendering

    The RST preview panel can now render image and figure directives as actual images, rather than displaying them as generic directive markup. Both local images (resolved relative to the source or document directory) and remote URLs are supported. Local image paths are securely served via VS Code’s webview URI mechanism.

    Images in RST preview

    To enable this feature, set ubcode.preview.experimentalRendering to true in your VS Code settings, or use the new toolbar toggle button in the preview panel. The toggle state persists across sessions.

    This complements the existing hover previews and missing-image diagnostics (image.not_found) introduced in earlier releases, providing a more complete image authoring experience within the editor.

    This is the first step toward a richer preview experience that we eventually hope to include items such as admonitions, syntax-highlighted code blocks, math equations, and diagram rendering (PlantUML, Mermaid, Graphviz).

0.22.0b1

Released:

20.02.2026

pre-release:

♻️ Refactor

  • Ported ublicense from Python to Rust

    The license management library has been fully rewritten in Rust, replacing the previous Python implementation. The port is feature-complete and includes online/offline licensing, OSS license detection, machine identification, HMAC-signed caching, and proxy support.

    This brings several benefits:

    • Faster license validation and caching

    • Improved error reporting with more granular error types

    • Stronger cache integrity

    Please test this pre-release and report any licensing issues you encounter.

0.21.0

Released:

19.02.2026

This release consolidates all changes from the 0.20.x pre-release series (0.20.0b1 - 0.20.6b1).

✨ New Features

  • Comprehensive schema validation

    Need extra options and links are now validated against JSON Schema during indexing, with support for typed fields (string, bool, int, float, list variants), custom needs.fields definitions, and needs.schema_definitions_from_json ontology rules. Real-time LSP diagnostics cover a broad set of JSON Schema constraints. Also available via the ubc schema validate CLI command.

  • Dead link validation

    Outgoing links targeting non-existent need IDs or part IDs now emit needs.dead_link diagnostics, with incremental re-checking and per-link-type opt-out via allow_dead_links.

  • Fine-grained lint suppression

    New lint.per-file-ignores and lint.message-ignores options allow targeted suppression of diagnostics by file glob pattern, code, or message substring.

  • needs.links dict-based configuration

    A new dict-based [needs.links] format for defining link types, aligning with the upcoming sphinx-needs v7 release.

  • Model Context Protocol (MCP) server

    Built-in MCP server in the VS Code extension provides programmatic access to project needs and metadata for external tools and AI systems.

  • Enhanced graph view

    Need graph visualization with configurable depth, toolbar controls, back/forward navigation, zoom, and “Go to Source” action.

  • Project comparison with ubc diff

    CLI command for comparing schemas and needs between projects or Git revisions, with HTML export and --deny-externals option.

  • Advanced filtering and querying

    Regex matching (=~ / search()), variable-to-variable comparisons, len(var) expressions, filter_data custom variables, and docname availability in global_options and needextend filters.

  • Variant options configuration

    needs.variant_options for defining variant-specific need option sets, with improved variant syntax parsing from sphinx-needs.

  • RST preview enhancements

    Click-to-source navigation, scroll sync toggle, and modernized toolbar.

  • Needs Index tree view improvements

    Grouping by type/status/tags, optimized server calls, and better performance.

  • CLI improvements

    -c / --config override option, ubc license config-file command, and --config-name support.

  • Missing image/figure warnings

    The indexer now emits image.not_found diagnostics for missing image or figure files.

  • Source follow links configuration

    New source.follow_links option to control source file link resolution.

👌 Improvements

  • Sphinx-needs v6 type safety: full type validation for need extra options with schema definitions.

  • Schema validation aligned with sphinx-needs (docname, is_external, is_import fields; all link fields included).

  • Deterministic diagnostic ordering (sorted by ID).

  • Improved diagnostic location reporting for needs.statuses and needs.tags.

  • Extra links copy key now supported.

  • Improved JSON import/export with better type handling and error reporting.

  • Improved RST autocompletion for need directive options.

  • Extension version displayed in VS Code home tree view.

‼️ Breaking Changes

  • Removed deprecated Kuzu database support

    The ubc build json-to-kuzu command, kuzu format option, and related Python bindings have been removed. Migrate to parquet or json formats instead.

🐛 Fixes

  • Fixed parse_variants = true on core fields being incorrectly rejected.

  • Fixed race conditions in Windows cache directory creation and openNeedView command.

  • Fixed edge-case “ID already registered” errors from duplicate links in LSP endpoints.

  • Fixed needextend unknown variable diagnostics not being emitted.

  • Fixed MCP server crash when query_needs was called by Claude model.

  • Fixed needs graph view “Focus on main need” button and zoom behavior.

  • Fixed missing VS Code configuration options not being registered.

  • Fixed deployment issue with incorrect platform binaries (0.20.1b1).

  • Fixed machine code handling for recent Windows 11 versions.

0.20.6b1

Released:

19.02.2026

pre-release:

✨ New Features

  • Dead link validation during indexing

    Outgoing links from needs are now validated against the index during indexing. When a link targets a non-existent need ID or part ID, a needs.dead_link diagnostic is emitted. Validation supports incremental updates, so only affected links are re-checked when needs change.

    Individual link types can opt out via the allow_dead_links option on the link definition.

  • Fine-grained lint suppression by path and message

    Two new [lint] configuration options allow targeted suppression of diagnostics:

    • lint.per-file-ignores — suppress specific diagnostic codes for files matching glob patterns:

      [lint.per-file-ignores]
      "tests/**/*.rst" = ["needs.dead_link", "needs.invalid_field_value"]
      
    • lint.message-ignores — suppress diagnostics whose message contains a given substring, optionally scoped to specific codes:

      [[lint.message-ignores]]
      codes = ["needs.invalid_field_value"]
      contains = "deprecated_field"
      

    These complement the existing lint.ignore (global code suppression) and lint.lsp_select (LSP-only override) options.

  • needs.links configuration

    Added a new dict-based [needs.links] configuration format for defining link types, as an alternative to the existing array-based [[needs.extra_links]] format. This aligns with the upcoming sphinx-needs v7 release (sphinx-needs#1649).

    [needs.links.implements]
    incoming = "is implemented by"
    outgoing = "implements"
    
    [needs.links.tests]
    incoming = "is tested by"
    outgoing = "tests"
    copy = true
    

👌 Improvements

  • Expanded real-time schema validation in the editor

    Quick schema validation for LSP diagnostics now checks a much broader set of JSON Schema constraints beyond enum values, including minLength, maxLength, minimum, maximum, minItems, maxItems, uniqueItems, and const. Link values are also now validated in real-time.

🐛 Fixes

  • Fixed parse_variants = true on core fields (status, tags, title) being incorrectly rejected when the field was not listed in variant_options. This now matches sphinx-needs behavior, which allows variants on these fields by default.

0.20.5b1

Released:

16.02.2026

pre-release:

👌 Improvements

  • Schema validation alignment with sphinx-needs

    Schema validation now includes docname, is_external, and is_import fields in the need JSON representation, enabling schema select clauses to filter by these properties. All defined link fields are now included in validation (even when empty), making link constraints like minItems validate consistently across all needs.

  • Deterministic diagnostic ordering

    Diagnostics related to needs are now emitted in a reproducible order, sorted by ID.

0.20.4b1

Released:

10.02.2026

pre-release:

✨ New Features

  • Schema definition validation now runs during indexing

    The needs.schema_definitions_from_json schema validation is now integrated into the indexing process, validating needs against your JSON Schema definitions automatically as you edit. Previously, this validation was only available via the CLI.

    This emits diagnostics with severity-specific codes:

    • needs.schema_definition_info - informational schema rules

    • needs.schema_definition_warning - warning-level schema rules

    • needs.schema_definition_violation - critical schema violations

    • needs.schema_network_info - informational network/link rules

    • needs.schema_network_warning - warning-level network rules

    • needs.schema_network_violation - critical network violations

    See Schema validation configuration for more details.

  • Regex support in need query syntax

    Added search() function and regex matching syntax (=~) to the need query language, enabling powerful pattern matching when querying needs. String literals now also support escape sequences for special characters.

  • Field specialization with needs.fields configuration

    A new needs.fields configuration allows you to define specialized field schemas, enabling fine-grained validation of need extra options with JSON Schema. Fields now default to nullable with no default value, providing more flexibility.

    This will support the future sphinx-needs v7 release.

👌 Improvements

  • Schema validation speed and robustness

    • Schema validation now uses forward link expansion for better incremental performance, reducing re-validation overhead when editing needs.

    • Schema validation now handles errors gracefully without raising exceptions

    • Improved error messages for field schema compilation errors

    • Fixed array type injection in schema validation

  • Improved ubc schema validate CLI

    The ubc schema validate command now has a consistent user experience with ubc build index, including improved progress output and error reporting.

  • MCP server improvements

    • Fixed crash when query_needs was called by Claude model

    • Added aliases to SortDirection for improved usability

  • Needs graph view fixes

    Fixed “Focus on main need” button and zoom behavior in the needs graph view.

‼️ Breaking Changes

  • Removed deprecated Kuzu database support

    The Kuzu graph database feature (introduced in v0.9.0) has been removed due to Kuzu being deprecated. The following have been removed:

    • ubc build json-to-kuzu command

    • kuzu format option from ubc build needs (-f kuzu)

    If you were using Kuzu databases, consider migrating to the parquet or json formats instead.

🐛 Fixes

  • Fixed edge-case “ID already registered” errors in VS Code caused by duplicate links in LSP endpoints.

0.20.3b1

Released:

27.01.2026

pre-release:

✨ New Features

  • Enhanced Need schema validation

    Comprehensive schema validation for need extra options and extra links has been added to the indexing process.

    These diagnostics emit the codes:

    • needs.invalid_field_value

    • needs.invalid_link_value

    See Fields configuration.

  • Grouping support in Needs Index tree view

    The Needs Index view now supports grouping needs by different properties (e.g., type, status, tags), making it easier to organize and navigate large sets of needs.

  • Click-to-source navigation in RST preview

    Clicking on elements in the RST preview now navigates directly to the corresponding source location in your editor.

  • Scroll sync toggle for RST preview

    A new toggle allows you to enable or disable scroll synchronization between the RST source and preview.

  • CLI configuration override option

    New -c / --config CLI option and UBCODE_CONFIG_OVERRIDE environment variable allow overriding configuration settings directly from the command line.

    See CLI documentation for more details.

  • Warning on missing image/figure files

    The indexer now warns when image or figure directive files are missing, helping catch broken references early.

    This diagnostic emits the code image.not_found code.

  • Source follow links configuration

    New source.follow_links configuration option to control how source file links are resolved. See source.follow_links configuration for more details.

👌 Improvements

  • Need Viewer enhancements:

    • Added back/forward navigation with history support

    • Added zoom controls for better readability

    • Added “Go to Source” context menu action

    • Improved performance with batch LSP endpoint for node data

  • RST preview toolbar modernization

    The RST preview toolbar has been updated to match the aesthetic of the Needs View.

  • Improved RST autocompletion for need directive options

    Better autocompletion suggestions when editing need directive options in RST files.

  • Improved diagnostic location reporting

    Diagnostic warnings for needs.statuses and needs.tags now report more accurate source locations.

  • Improved MCP server handshake

    Fixed compatibility issues with the VS Code MCP server handshake.

  • Needs Index tree view optimization

    Reduced server calls for improved performance when browsing needs.

  • Schema file handling

    The indexer now warns on missing schema files rather than erroring, improving resilience.

  • License CLI improvements

    Added ubc license config-file command and --user option to ubc license show.

  • Extension version in home tree view

    The VS Code extension version is now displayed in the home tree view for easier identification.

🐛 Fixes

  • Fixed race condition in Windows cache directory creation.

  • Fixed race condition in the openNeedView command.

  • Fixed missing VS Code configuration options not being registered.

‼️ Breaking Changes

  • Removed deprecated Kuzu database support

    The Kuzu graph database feature (introduced in v0.9.0) has been removed due to Kuzu being deprecated. The following have been removed:

    • ubc build json-to-kuzu command

    • kuzu format option from ubc build needs (-f kuzu)

    • kuzu Python dependency

    • kuzu_need_table_cmd Rust function and Python binding

    If you were using Kuzu databases, consider migrating to the parquet or json formats instead.

0.20.2b1

Released:

10.12.2025

pre-release:

👌 Improvements to filtering

Within needs.global_options predicate filters, needimport and needextend filters, the needs.filter_data configuration can now be used to define additional variables for use in filter expressions.

Within needs.global_options predicate filters, needextend filters, additionally, the docname variable is now available. For needextend this is derived from the document path containing the directive, and for needs.global_options it is derived from the document path the need is defined in, for need and needimport directives. The docname is the path relative to project.srcdir, without the file extension (as per Sphinx’s standard document naming).

This improves compatibility with sphinx-needs filtering.

For example:

project.srcdir = "docs/source"

[needs.filter_data]
my_var = "a"

[needs.global_options.status]
default = "open"
predicates = [
  ["my_var == 'a'", "closed"]
  ["docname == 'index'", "other"],
]
.. needextend:: docname == 'some_doc' and my_var == 'a'
   :status: another

👌 Additional improvements

  • The copy key of needs.extra_links item configurations is now supported, as per the logic of sphinx-needs. See Extra links configuration for more details.

  • Improvements to the Model Context Protocol (MCP) server: The need query input and return value schemas, and usage instructions, have been improved, to allow for easier interpretation by LLMs and reduce token usage.

  • Addition of the --deny-externals option to the ubc diff command. This filters out external needs from the diff analysis, which is helpful when reviewing Git history, to focus only on local project changes, and to avoid false positives when external needs.json files are dynamically generated and may not be available.

    If projects use dynamically generated external needs.json files, e.g. build via Bazel, those will not be available when running ubc diff git or before Bazel was called. The feature can be used to avoid false positives.

🐛 Fixes

  • Diagnostic warnings for unknown variables in needextend are now correctly captured and emitted. For example:

    .. needextend:: unknown_variable == 'value'
       :status: closed
    
  • ublicense: Fix machine code handling for recent versions of Windows 11

0.20.1b1

Released:

17.11.2025

pre-release:

🔧 Fixes

This pre-release fixes an issue with the deployment of the last pre-release, whereby for some platforms incorrect binaries were bundled with the VS Code extension.

0.20.0b1

Released:

12.10.2025

pre-release:

New and Improved

  • Enhanced Type Safety with Sphinx-Needs v6 Compatibility

    ubCode now includes comprehensive typing support to mirror sphinx-needs v6.

    This includes:

    • Added schema option to the need extra options configuration, allowing you to define and enforce value types for custom need fields

    • Full type validation for need extra options (string, bool, int, float, and list variants)

    • Improved handling of nullable extra options for more flexible need definitions

    • Type-aware filtering and querying of needs

    For example:

    [[needs.extra_options]]
    name = "effort"
    description = "Story points (Fibonacci sequence)"
    
    [needs.extra_options.schema]
    type = "integer"
    enum = [1, 2, 3, 5, 8, 13, 21, 34]
    description = "Must be a Fibonacci number"
    

    See Fields configuration for more details.

  • Ontology Schema Validation

    New (experimental) CLI command ubc schema validate provides comprehensive validation of your project’s need schema and ontology:

    • Validates need type definitions against configured schemas (using the needs.schema_definitions_from_json configuration)

    • Checks consistency of extra options and their types across the project

    • Ensures compliance with ontology rules and constraints

    • Provides detailed error reporting for schema violations

    ubc schema validate
    

    See the Configuration and CLI documentation for more information.

  • Model Context Protocol (MCP) Server Integration

    The VS Code extension now includes a built-in MCP server that provides:

    • Programmatic access to project needs and metadata

    • Query interface for external tools and AI systems

    See the MCP server documentation for more details on using the MCP server.

  • Enhanced Graph View with Extended Depth

    Significant improvements to the need graph visualization:

    • Added toolbar with configurable maximum distance buttons for exploring need relationships

    • Extended depth graph traversal for better visualization of complex need hierarchies

    • You can also now open the needs graph view directly from a need directive in your rST files, or from the command pallete.

    Needs Graph View

    Needs Graph View

    See the needs graph view documentation for more information on using the graph view.

  • Project Comparison with Diff Command

    New CLI command ubc diff enables comparison of schemas and needs between two projects:

    • Compare need schemas across different project versions

    • Identify differences in need definitions, types, and configurations

    • Export comparison results in multiple formats

    • Useful for project evolution tracking and compatibility checking

    • Capability to look into the Git history

    See the CLI documentation for more information.

    ubc diff --project project1/ --project project2/
    ubc diff --format html -o report.html --project project1/ --project project2/
    ubc diff --needs _build/needs.json --project project2/
    ubc diff git
    
  • Advanced Filtering Syntax

    Expanded filtering capabilities with new syntax support:

    • Variable-to-variable comparisons

    • Support for len(var) expressions in Python queries

    • Enhanced string operations like "text" in var.upper()

    • Improved type handling for list[bool] variables

    See the Filtering documentation for more details.

  • Variant Options Configuration

    Added needs.variant_options configuration option:

    • Define variant-specific need option sets

    • Support for conditional need field configurations

    • Enhanced flexibility in multi-variant documentation projects

    • Improved variant syntax parsing from sphinx-needs

    variant_options = ["status", "priority", "assignee"]
    

    See the Variants configuration for more details.

  • Improved JSON Import/Export

    Enhanced handling of needs data in JSON format:

    • Better support for importing needs with complex type structures

    • Improved error handling when importing needs with invalid field types

    • More robust JSON export capabilities for needs data

    • Enhanced testing and validation of JSON import/export workflows

0.19.1

Released:

08.10.2025

  • 👌 Add --config-name option to CLI commands, for overriding the configuration file name (default ubproject.toml).

  • 🐛 Fix file discovery hanging. This reverts a change from 0.19.0, which caused file discovery to hang in certain cases.

0.19.0

Released:

18.09.2025

New and Improved

  • ✨ Add need graph view to VS Code extension

    This view shows a graphical representation of a need in the current project, along with its incoming and outgoing links.

    The graph is interactive, allowing for zooming, panning, and clicking on nodes to reveal more information about each need.

    See also

    The needs graph view documentation for more information on using the graph view.

0.18.1

Released:

09.09.2025

Fixes

  • 🐛 FIX: Relative paths in symlinked ubproject.toml

    Relative paths are now resolved relative to the location of the symlink, rather than the real file location it links to, for example:

    extend = "../parent.toml"
    project.srcdir = "source"
    

    A key use-case this fixes is within Bazel use, when the entire project is symlinked to a different location.

  • 🐛 Fix OSS license detection in certain user environments

0.18.0

Released:

02.09.2025

New and Improved

  • ✨ Free usage for OSS repos

    ubCode is now free to use for open source projects! See the licensing section for more details.

  • ✨ Add doc references to VS Code std domain tree view

  • ✨ Add VS Code jump-to-definition for doc and term roles

  • 👌 Add --srcdir option to ubc build targets CLI command.

    To allow for override of the project.srcdir. Additionally, issue with generating docname’s are logged in debug mode.

0.17.0

Released:

21.08.2025

New and Improved

  • ✨ Add parsing of glossary directives and gathering of term reference targets, for example:

    .. glossary::
    
      term1
      term2
          Definition of term1.
    

    These are now viewable in the VS Code standard domain index tree view, and are output in the objects.inv, when running ubc build targets --format inv.

  • ✨ Add initial capture of reference target implicit titles, for example the target_name below will have the title A Title:

    .. _target_name:
    
    A Title
    =======
    

    These are now viewable in the VS Code standard domain index tree view, and are output in the objects.inv, when running ubc build targets --format inv.

0.16.0

Released:

12.08.2025

New and Improved

  • ✨ Add Jump to definition, for standard domain references, in the VS Code extension.

  • ✨ Experimental output of objects.inv via CLI: ubc build targets --format inv. This will output a Sphinx objects.inv file (see intersphinx), which can be used for cross-project references. Note, this is an experimental feature, that does not yet capture all data that sphinx does, and may change in future releases.

  • ✨ Capture document titles when indexing. This is taken from the first section heading in the document, if present, and is included in the built objects.inv file above as doc targets implicit titles.

  • ✨ Add ubc build list-documents CLI command, to print out a list of the documents that would be indexed for a project.

Fixes

  • 🐛 Fix source config include/exclude glob pattern resolution. This is intended to follow ruff file discovery, but was not resolving user supplied glob patterns relative to the root of the project. See source configuration for more details.

0.15.0

Released:

18.07.2025

New and Improved

✨ Added indexing, duplicate diagnostics and VS Code tree view support for standard cross-project reference targets.

Targets are gathered from reStructuredText block, inline and citation syntax, and certain directive name options, e.g.

.. _target_name:
.. [citation_name] A citation

.. note::
   :name: target_name2

   This is an _`inline` target.

Target names are case and whitespace normalised, as per the Sphinx specification.

Additionally, these targets, plus footnote and substitution definitions, are diagnosed for duplicate names at a local file level, and issues are highlighted in-line within the text editor. New diagnostic codes are:

  • std.duplicate_target

  • std.duplicate_citation

  • std.duplicate_footnote

  • std.duplicate_substitution

Fixes

  • 🐛 Fix substitution definition parsing and formatting. The content of substitution definitions is now correctly parsed, allowing for language features (e.g. autocompletion) to work within them.

    .. |substitution_name| replace:: This is replacement text with **bold** text and *italic* text.
    

0.14.0

Released:

02.07.2025

New and Improved

Added autocompletion and hover previews for image and figure directives in rST files.

Autocompletion is triggered after typing / as the last character of the argument, and if not a remote or embedded (data) image. As per sphinx, this will complete relative to project.srcdir (defaults to ubproject.toml folder) if the argument starts with / or relative to the document’s directory otherwise. Also as per sphinx, arguments are “normalised” to resolve backslash-escapes and remove unescaped spaces.

Completions will be shown for all image files found in the source tree, that (a) are not gitignored, and (b) adhere to a set of file patterns, configurable in ubproject.toml.

Hover previews will show if the image is remote, embedded or found locally and has an HTML compatible file extension, or if the extension is the * wildcard and a file with a compatible extension is found. This can also be activated or deactivated in the ubproject.toml file.

.. image:: /path/relative/to/srcdir/image.png
.. figure:: ./path/relative/to/document/image.*
.. image:: https://remote.server/image.png
.. image:: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
[server]
image_file_patterns = ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.svg", "*.webp", "*.bmp", "*.tiff", "*.tif", "*.ico", "*.heif", "*.heic", "*.avif", "*.eps", "*.psd", "*.ai", "*.pdf"]
hover_images = true

Fixes

  • 🐛 Show correct total issue count, for the VS Code diagnostic tree, when there are greater than 10,000 issues.

0.13.0

Released:

15.06.2025

New and Improved

Added quick look-up features for needs in the Language server and VS Code extension: ubCode now creates a fast-lookup index for needs, which allows for quick access to need details and references. This index has allowed for the following feature implementations, in this release, and more to come in the future.

  • ✨ need ID autocompletion (note these can be triggered by CTRL+SPACE):

    Autocompletion can be activated for need, need_incoming and need_outgoing roles, after the first backtick and for partial IDs, for example cursor positions:

    :need:`
           ^
    :need_incoming:`partial`
                           ^
    

    They can also be autocompleted for directive link options, such as:

    .. req:: A need with a link
       :link_name1:
                    ^
       :link_name2: id1,partial
                              ^
    

    New IDs are also suggested for the id option of need directive, based on the configured need type prefix (in ubproject.toml) and the “next available” integer suffix.

    .. req:: A need with no ID yet
       :id:
           ^
    
  • ✨ need ID hover information

    Hovering over a need ID in a role or directive link option will show basic details of that need.

    This can be enabled/disabled in the ubproject.toml, by setting the server.hover_need_id configuration option to true or false:

    [server]
    hover_need_refs = true
    

Additionally, the following features have been added:

  • ✨ Added “Go to source” for links in VS Code needs tree view

  • 👌 Added part ID source retrieval for VS Code needs tree view

Fixes

  • 🐛 rST formatter: fix underline length for title with emojis

  • 🐛 quickstart: fix naming of incoming/outgoing link names

0.12.0

Released:

12.05.2025

New and Improved

This release introduces a new formatter for reStructuredText (rST) files. It can be used via:

  1. The VS Code extension, to format complete documents (ALT+SHIFT+F) or selections of text (CTRL+K CTRL+F)

  2. The ubc format CLI command to format one or more files/folders. Note, currently one must use ubc format --preview to run this command, since the functionality is in Beta.

  3. A ubc format --check CLI command option, to check if file contents would have changed during formatting, but not actually modify the files. If any would change then a non-zero exit code is emitted.

Note, in order to ensure the formatter preserves the original “syntax structure” of the text, a comparison is made, between the original and formatted syntax, before the formatted text is written to file. If there are differences, the formatting will error and the new content will not be written.

On trialling the formatter on known projects, it was found that this comparison could fail when formatting blockquotes, i.e. indented blocks of text, since changes in indenting relative to preceding syntax blocks could change its interpretation. Moreover, these existing blockquote blocks were often an unintended result of mis-indented text, e.g.

* bullet point

   block quote as part of bullet item

 block quote after bullet list

Therefore, a linting rule has also been added warning against bare blockquotes, in favour of using specific directives:

block.bare_blockquote: Bare blockquotes can lead to ambiguous parsing, instead use the pull-quote or epigraph directives.

This rule then encourages the more explicit syntax:

* bullet point

  .. pull-quote:: block quote as part of bullet item

.. pull-quote:: block quote after bullet list

0.11.0

Released:

17.04.2025

New and Improved

  • ✨ Add server.index_on_save configuration

    Setting server.index_on_save = true in the ubproject.toml will cause the project indexing be triggered for every save of a file in that project (currently only .rst files).

  • ✨ Add ubc quickstart

    For creating an new example ubCode project.

  • ✨ Add handling of need parts, including:

    • Parsing:

      • parse need_part / np roles and storing parts in the needs index

      • parse parts sections in needs.json, for external and imported needs

    • Diagnostics

      • Creating warnings for need_part / np roles that are not within need directives

      • Create warnings for need / need_incoming / need_outgoing that reference non-existent ID.PART_ID

    • Writing

      • Write parts section to needs.json

    • VS Code

      • Show parts in needs index tree view (including jump-to-part)

      • Jump to defining need_part / np role, from need / need_incoming / need_outgoing roles

      • Show references from need_part / np role

      • “Select ID” in needs index tree view, from need_part / np role

  • 👌 Correctly handle title_from_content option in needs directives

  • 👌 Correctly handle id_prefix for links in external and imported needs

Fixes

  • 🐛 Do not show empty outgoing link sections in VS Code needs index tree view

0.10.0

Released:

11.04.2025

New and Improved

  • ✨ Parse need, need_incoming and need_outgoing roles.

    These roles are now stored in the index, allowing for:

    • “Referencing Roles” section of the LSP needs index view, per need

    • “Jump-to-definition” and “Find all references” when selecting the role

    • Roles are included in “Find all references” for the need ID

    • needs.link_ref diagnostics are emitted for roles referencing unknown need IDs

  • ✨ Add config lint.lsp_select

    Specify a list of linting codes to select in LSP file diagnostics, which overrides the lint.ignore list. This is useful for users transitioning to ubcode, who want to ignore existing linting violations in CI checks, but show them to users in the VS Code extension.

0.9.0

Released:

07.04.2025

New and Improved

  • ✨ First official release on the VS Code Marketplace.

    With this version the ubCode extensions leaves the pre-release state.

    Note

    The extension is made available in a release state for better accessibility. It should be noted though, that ubCode is still in beta phase and not yet feature complete in terms of Sphinx-Needs support.

  • ✨ First official release of the ubCode CLI app ubc.

    The CLI provides a way to view all diagnostics of projects in the terminal. Projects can be built and exported to various formats. Finally, licenses can be viewed and activated.

    Download ubc for your platform from:

    The files are directly executable on all platforms and have no dependencies. The first execution might be a bit slower due to the bootstrapping process of the application.

    See the ubc CLI section for latest links and installation instructions.

  • ✨ Add dynamic function parsing

    ubCode is now aware of the dynamic function syntax (e.g. [[func()]]) and checks for syntax errors. Dynamic functions are not yet executed, but will no longer show in link ID lists.

  • ✨ Write Kuzu DB from needs.json

    A needs.json can now be converted to a Kùzu graph DB. Kùzu version is 0.9.0 (storage version 37).

Fixes

  • 🐛 Omit ignored diagnostics codes from diagnostic tree view

  • 🐛 Omit warnings for allowed global_options constraints/layout/style keys

0.8.0

Released:

13.03.2025

Breaking Changes

The handling of licenses has been refactored to handle more licensing scenarios, including offline licenses and system proxies for license activation.

This has necessitated a change in the configuration file format, from ubcode.key.text to ubcode.toml, and must now also include a user e-mail/identifier:

[license]
key = "AAAAA-BBBBB-CCCCC-DDDDD"
user = "mail@example.com"

See License configuration for more information.

New and Improved

  • ✨ Add Diagnostics tree view to VS Code.

    This view shows all diagnostics encountered during the project index, such as linting errors and duplicate need IDs, and allows for filtering by diagnostic code

  • ✨ Add handling of needs.global_options configuration.

    This allows for the definition of defaults for need fields. It follows the new format as introduced in sphinx-needs v5.1.0 (see needs_global_options for more information).

0.7.0

Released:

25.02.2025

Breaking Changes

  • The configuration section rst_lint has been renamed to lint. See Linting for details.

New and Improved

  • ⚡️ Improve speed of index build: the index build is now ~33% faster for large projects.

  • ✨ Add support for Python filter expressions in need queries. See Python syntax for details.

    This is exposed in the needs index view in VS Code, using the “Select ubcode need ID or filter in view” command, and allows for support of the filter option in needimport and needextend directives.

  • ✨ Compute closest match for unknown directive name/option

    This is used to provide quick fixes for unknown directive names and need directive options.

0.6.2

Released:

04.02.2025

Fixes

  • 🐛 ubCode Marketplace URLs

0.6.1

Released:

04.02.2025

New and Improved

  • 👌 Add quickstart command

  • 👌 Add chain option to the scripts configuration

  • 📚 Improve the documentation

0.6.0

Released:

03.02.2025

New and Improved

  • 👌 Add diagnostic for unknown need directive options.

  • 👌 Add autocompletion of needextend directive options.

  • ✨ Add need directive status auto-completions, with items from needs.statuses configuration, if set.

  • 👌 Add config needs.external_needs.skip_in_ubcode, which will skip reading of the external source when indexing.

  • ✨ goto definition / references for need directive links, when cursor is on the link value:

    .. req::
      :link_name: value
                  ^^^^^
    
  • ✨ Add “select ubcode ID in view” command. Available in command palette or right-click menu.

  • ✨ Add scripts configuration and use in VS Code, for defining/running commands in the terminal (see scripts):

    [scripts]
    sphinx = "sphinx-build -b html . _build/html {{filepath}}"
    sphinx = { cmd = "sphinx-build -b html . _build/html {{filepath}}", env.SPHINXOPTS = "-W", terminal = "name", jinja = true }
    

    In VS Code they can be accessed via the command palette (Ctrl+Shift+P) by selecting “ubCode: Run Command in Terminal”.

  • 👌 Add Project item to needs index view, with configuration, current file and indexing issues children.

  • 👌 Add n.is_directive, l.type, o.id filter fields for needs index view.

  • 👌 Persist needs index view filter query, when re-starting VS Code.

  • ✨ Add context button to open external URLs in need index view, for needs originating from external sources. These are resolved from the base_url / target_url on the extend_needs configuration.

  • 👌 Add restart server button to home view.

0.5.0

Released:

29.01.2025

New and Improved

  • ✨ Cache license checks for offline use. The remote license check is now cached for 3 days, allowing for offline use during this time.

  • ✨ Add processing of needextend directives. These directives are now gathered and applied to the needs index. Needs with associated needextend can be filtered for in the index tree view, using the n.is_modified filter expression.

    Note, currently only needextend with “single ID” filters are applied; expression filter processing is planned for a future release.

  • 👌 Make external need reads more fault tolerant. External needs.json with invalid extra/link field value types will no longer error the entire read. Instead, the errors are stored (and reported in the tree view) and the fields are skipped.

  • ✨ Add Linux ARM64 build target

0.4.0

Released:

22.01.2025

New and Improved

  • ✨ Add external and import needs parsing:

    • Add needs.import_keys configuration

    • Add project.srcdir configuration (to resolve needimport sources starting with /)

    • Note, the filter option of needimport is not yet supported

  • VS Code index tree view:

    • ⚡️ Improve performance of updates and item expansion

    • ✨ Show need indexing issues

    • 👌 Expand querying capabilities

    • 👌 Add copy link ID to clipboard buttons for incoming/outgoing need links

  • 👌 Improve rst-preview CSS: do not word-wrap directive option names

  • 👌 Complete find references on directive id named_option

0.3.0

Released:

12.12.2024

New and Improved

  • ⚡️ Improve performance of diagnostics/needs index builds.

    Including parallel file reads, better caching, and background (non-blocking) processing.

  • ✨ Add initial filtering of needs in index tree-view.

    Using a sub-set of the Cypher query syntax.

    Note, currently it is constrained to n.id and n.type queries; this will be expanded in the future.

  • ✨ Add find references for need directives.

    Activated by placing the cursor on the directive name, and using the context menu or pressing SHIFT+F12.

  • ✨ Add quick fix for inline.role_no_name diagnostic.

  • 👌 Add index directive to built-ins.

  • ✨ Add “Re-index project” to VS Code command palette.

  • ✨ Add “Remove project cache” to VS Code command palette.

  • 👌 Open license path from VS Code Home tree.

0.2.3

Released:

03.12.2024

New and Improved

  • ✨ Add : role and directive option auto-completions

  • ✨ Allow for named_options to be specified on parse.extend_directives (see Parsing)

0.2.2

Released:

24.11.2024

Improved

  • ✨ Add extend configuration, for sharing configuration between multiple projects (see Top-level options)

  • ✨ Add auto-completion and hover information of directives in rST files

  • 👌 Graph DB performance improvements

0.2.1

Released:

21.11.2024

Fixes

  • 🐛 Build manylinux2014 compatible wheels to support systems such as Ubuntu 20.04 LTS

0.2.0

Released:

20.11.2024

Initial release of the new ubCode VS Code extension.

This is a complete rewrite of the existing ubCode extension (v0.1.2).

This version features a new language server that understands RST, generates HTML previews in real-time and provides diagnostics for RST problems.

The extension integrates with Sphinx-Needs via a new ubproject.toml file format. The new needs index can be used to navigate to needs without running a Sphinx build.