Skip to content

docs: add VitePress documentation site#157

Merged
PatrickRitchie merged 39 commits into
TrakHound:masterfrom
ottobolyos:feat/vitepress-docs
May 31, 2026
Merged

docs: add VitePress documentation site#157
PatrickRitchie merged 39 commits into
TrakHound:masterfrom
ottobolyos:feat/vitepress-docs

Conversation

@ottobolyos
Copy link
Copy Markdown
Contributor

@ottobolyos ottobolyos commented May 4, 2026

Summary

This branch delivers four things: a VitePress documentation site for the repository, a build gate that treats missing XML documentation as an error across the shipped libraries, a SysML-importer extension plus regeneration so every generated file is fully documented, and a concepts + migration narrative that pairs with the v7 agent-validation work now on master.

Documentation site

A VitePress site rooted at the existing top-level docs/ directory, with Mermaid diagrams enabled for architecture, sequence, class-relationship, state-machine, and wire-flow diagrams. The site documents the full repository: every shipped library and module, every CLI tool, every wire format and codec, every configuration option, the public-surface API, and the project's MTConnect Standard compliance posture.

Top-level navigation:

  • Compliance -- per-version compliance matrix, wire-format compliance, spec-source-vs-implementation cross-references, known divergences, compliance test harness.
  • Configure & Use -- install, agent configuration, adapter configuration, module configuration, integrations (InfluxDB, MQTT broker / cloud / TLS).
  • Concepts -- Devices, Components, Data Items, Observations, Assets, Relationships, and the agent validation events family.
  • API reference -- auto-generated per-type pages with namespace cross-links.
  • Wire formats -- XML, JSON v1, JSON-CPPAGENT (v2), JSON-CPPAGENT-MQTT, SHDR, with sample envelopes, codec class names, and wire-flow diagrams.
  • Modules -- HTTP server, MQTT broker, MQTT relay, MQTT adapter, HTTP adapter, SHDR adapter, and the adapter-side SHDR / MQTT outputs.
  • CLI -- Agent and Adapter CLI references plus the contributor tools/dotnet.sh, tools/test.sh, and SysML importer.
  • Cookbook -- write an agent, write an adapter, write a module, configure the MQTT relay, write a JSON-MQTT consumer, migrate between versions.
  • Migration notes -- per-version migration playbooks, starting with the v7 ValidationResult consolidation.
  • Troubleshooting -- common error modes, XSD validation failures, schema-version mismatches, MQTT TLS handshake issues.

Auto-generated API reference

The API reference under docs/api/ is generated by docfx from the Debug net8.0 build of every shipped library DLL plus its XML doc file. The configuration lives at docs/.docfx/docfx.json; the regeneration script at docs/scripts/generate-api-ref.sh compiles each library with -p:GenerateDocumentationFile=true and then runs docfx metadata, producing a flat Namespace.Type.md layout that VitePress consumes directly.

The per-type pages are gitignored and regenerated on every build, so the repository does not carry a stale copy of the API surface. The section landing page docs/api/index.md is the only tracked file under docs/api/.

The legacy v1 MTConnect.Assets.Json.CuttingTools.JsonProcessFeedrate shadows the cppagent v2 JsonProcessFeedRate on a case-insensitive module path; the legacy type is excluded via docs/.docfx/filter.yml so the module resolver does not collide on the case-variant pair. The cppagent v2 type stays in the reference.

Documentation gate

libraries/Directory.Build.props treats CS1591 (missing XML documentation comment) as a build error for the production libraries, so the API reference cannot regress to undocumented members. Every hand-authored and generated public, internal, and private type and member carries a substantive doc comment describing its contract.

SysML importer and regeneration

The SysML importer in MTConnect.NET-SysML is extended so the CompositionState and Direction event subtype value vocabularies (one enumeration per subtype) and the shared CuttingTool Measurement base are materialized as documented generated output instead of stale orphan files. The MTConnect.NET-Common library is regenerated from the mtconnect/mtconnect_sysml_model v2.7 tag; regeneration is deterministic, and stale v2.3 generator output superseded by the v2.7 equivalents has been removed.

Concepts: agent validation events

docs/concepts/agent-validation-events.md documents the full Invalid*Added family on MTConnectAgent from both the consumer and the contributor perspective: why the agent emits events instead of throwing, how each event maps to a delegate, the uniform handler signatures, the InputValidationLevel knob that gates everything, the per-failure-category ValidationResult.Code values, and the naming convention plus call-site pattern for adding a new family member. The page covers all six current entries (InvalidDeviceAdded, InvalidComponentAdded, InvalidCompositionAdded, InvalidDataItemAdded, InvalidObservationAdded, InvalidAssetAdded), including the pre-flight ValidateDevice(IDevice) helper that exposes the same check AddDevice runs internally.

Migration note: v7 ValidationResult consolidation

docs/migration/v7-validation-result.md is the migration playbook for the v7 collapse of three pre-v7 per-domain validation result structs (MTConnect.Assets.AssetValidationResult, MTConnect.Devices.DataItems.ValidationResult, MTConnect.Observations.ObservationValidationResult) into one universal MTConnect.ValidationResult with an added machine-readable Code property. Covers the type-replacement table, the Valid() / Invalid(code, message) factory shorthand, and before/after code samples for both the handler side (agent subscribers) and the Asset author side (Asset.IsValid overrides). Reachable via a new /migration/ sidebar group, which future migration notes can join.

CI

.github/workflows/docs.yml runs on every push and pull request to master. Each run sets up .NET 8.0 and Node 20, installs docfx, runs docs/scripts/generate-api-ref.sh, then npm run build inside docs/. On push to master the built site is uploaded as a Pages artifact and the deploy job publishes it to GitHub Pages. Action versions are SHA-pinned with tag aliases in trailing comments.

docs/package.json lives inside docs/; a !docs/package.json allow-list entry was added to .gitignore because the repository's blanket package.json ignore targets the legacy gulp-era build artefacts.

@PatrickRitchie
Copy link
Copy Markdown
Contributor

It looks like the package.json file may be missing. Possibly filtered out of the git?

@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch from f2e0087 to 33ca82f Compare May 13, 2026 22:08
@ottobolyos ottobolyos marked this pull request as ready for review May 13, 2026 22:10
@ottobolyos ottobolyos marked this pull request as draft May 14, 2026 05:39
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch 3 times, most recently from dc4ae50 to 68a5453 Compare May 18, 2026 21:58
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch 5 times, most recently from ae35d66 to 903215a Compare May 20, 2026 08:47
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch from 408f944 to 655f7c8 Compare May 22, 2026 13:49
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch from 189a4b6 to 53b0ae4 Compare May 27, 2026 08:31
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request May 27, 2026
The InvalidDeviceAdded event family added in PR TrakHound#169 introduced a new
OnInvalidDeviceAdded method on MTConnectAgent. After rebasing TrakHound#157
(CS1591 promoted to error) onto the integration tip, this method needs
an <inheritdoc /> tag matching the documented interface method.
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch 2 times, most recently from 796c0f3 to 783bf1b Compare May 27, 2026 18:03
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request May 27, 2026
The InvalidDeviceAdded event family added in PR TrakHound#169 introduced a new
OnInvalidDeviceAdded method on MTConnectAgent. After rebasing TrakHound#157
(CS1591 promoted to error) onto the integration tip, this method needs
an <inheritdoc /> tag matching the documented interface method.
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request May 27, 2026
The InvalidDeviceAdded event family added in PR TrakHound#169 introduced a new
OnInvalidDeviceAdded method on MTConnectAgent. After rebasing TrakHound#157
(CS1591 promoted to error) onto the integration tip, this method needs
an <inheritdoc /> tag matching the documented interface method.
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch 2 times, most recently from 1ea4df6 to 24d603f Compare May 28, 2026 01:25
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request May 28, 2026
The InvalidDeviceAdded event family added in PR TrakHound#169 introduced a new
OnInvalidDeviceAdded method on MTConnectAgent. After rebasing TrakHound#157
(CS1591 promoted to error) onto the integration tip, this method needs
an <inheritdoc /> tag matching the documented interface method.
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request May 28, 2026
The InvalidDeviceAdded event family added in PR TrakHound#169 introduced a new
OnInvalidDeviceAdded method on MTConnectAgent. After rebasing TrakHound#157
(CS1591 promoted to error) onto the integration tip, this method needs
an <inheritdoc /> tag matching the documented interface method.
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch from 24d603f to e37b1fb Compare May 28, 2026 02:52
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request May 28, 2026
The InvalidDeviceAdded event family added in PR TrakHound#169 introduced a new
OnInvalidDeviceAdded method on MTConnectAgent. After rebasing TrakHound#157
(CS1591 promoted to error) onto the integration tip, this method needs
an <inheritdoc /> tag matching the documented interface method.
The InvalidDeviceAdded event family added in PR TrakHound#169 introduced a new
OnInvalidDeviceAdded method on MTConnectAgent. After rebasing TrakHound#157
(CS1591 promoted to error) onto the integration tip, this method needs
an <inheritdoc /> tag matching the documented interface method.
… family

Promote InvalidDeviceAdded from "in flight" to a first-class entry in
the event family table, with its own row describing when it fires
(Device null or Uuid null/empty). Add a validation-code reference table
covering DeviceNull and DeviceUuidMissing, the two codes the agent
currently stamps onto these failures. Add a pre-flight section showing
how ValidateDevice exposes the same check for callers who want to
validate before AddDevice. Update the wire-up example to attach a
handler for InvalidDeviceAdded, and update the handler-signature
listing so every delegate (including MTConnectAssetValidationHandler)
carries the new universal MTConnect.ValidationResult instead of the
per-domain structs.
Three pre-v7 per-domain validation result structs
(MTConnect.Assets.AssetValidationResult,
MTConnect.Devices.DataItems.ValidationResult,
MTConnect.Observations.ObservationValidationResult) collapsed into one
universal MTConnect.ValidationResult in v7. Add a dedicated migration
page covering the type-replacement table, the new Code property and
its rationale, and before/after code samples for both the handler
side (agent subscribers) and the Asset author side (Asset.IsValid
overrides). Register a /migration/ sidebar so the page is reachable
without typing the URL by hand; future migration notes can join the
same group.
After rebasing onto integration/all-fixes, the docs-completeness gate
flagged docs/reference/http-api.md as out of sync with the source. Run
MTConnect.NET-DocsGen --repo . to regenerate it; the diff is a section
removal driven by changes upstream in PR TrakHound#169's consolidation work.
The library was removed in PR TrakHound#172 (chore/remove-http-aspnetcore).
Strip every docs mention:

- Renderers.cs: drop the AspNetCore section heading + RenderTable call
  and update the intro/taxonomy prose (removed "either transport").
- docs/api/index.md: remove the exclusion note that explained why
  AspNetCore was absent from the API reference -- the library is gone,
  not just excluded.
- docs/reference/http-api.md: regenerated by running
  build/MTConnect.NET-DocsGen after the renderer fix; produces a
  Ceen-only page with 13 endpoints and no AspNetCore section.

No sidebar entries, no migration notes, and no module/configure pages
required changes -- only the two reference pages carried AspNetCore text.
All 6 docs-completeness tests pass; VitePress build green.
…ily style

Use the same terse one-line summary the rest of the
MTConnect{Component,Composition,DataItem,Observation,Asset}ValidationHandler
family uses, rather than spelling out the rejection scenario inline. The
when-it-fires detail lives on the docs/concepts/agent-validation-events.md
page (user POV) and on the ValidationResult.Code values; the delegate's
own summary just identifies what it handles.
@ottobolyos ottobolyos force-pushed the feat/vitepress-docs branch from 93dcbaa to f2828f2 Compare May 28, 2026 16:58
@ottobolyos ottobolyos marked this pull request as ready for review May 28, 2026 17:04
@ottobolyos ottobolyos marked this pull request as draft May 28, 2026 17:45
The docs reference generator extracted XML-doc summaries by splitting on
'\n' and trimming only leading whitespace, so a CRLF-checked-out source
file (the default on Windows) left a trailing '\r' on every summary line.
That '\r' survived into docs/reference/http-api.md and configuration.md,
making the generated markdown differ from the LF-committed pages and
failing DocsReferenceGenerationTests on the windows-latest CI leg while
passing on ubuntu. Strip the trailing '\r' in both ExtractSummary
(ConfigInventory) and CleanXmlText (RouteInventory); cli.md already
stripped it, so harden its remaining split site too.

Also pin the file-enumeration order: Directory.EnumerateFiles /
Directory.GetFiles return entries in a filesystem-dependent order, so add
an ordinal sort on the path plus FileRelativePath/Line tiebreakers on the
final result sorts to keep collection order identical across operating
systems.
@ottobolyos ottobolyos marked this pull request as ready for review May 28, 2026 17:49
@ottobolyos ottobolyos marked this pull request as draft May 28, 2026 19:51
@ottobolyos ottobolyos marked this pull request as ready for review May 28, 2026 20:01
@ottobolyos
Copy link
Copy Markdown
Contributor Author

One thing to flag before this merges, since it needs a decision only you can make.

The Docs site workflow (.github/workflows/docs.yml) has two jobs: Build VitePress site and Deploy to GitHub Pages. On a pull request the deploy job is intentionally skipped — it's gated if: github.event_name == 'push' && github.ref == 'refs/heads/master', so PRs build the site only (which is why you see Deploy to GitHub Pages showing as skipped on this PR), and a doc-breaking change still surfaces in the build job. That part is by design.

The decision is what should happen once this lands. On the push-to-master that the merge produces, the deploy job's condition becomes true and actions/deploy-pages will attempt to publish the built site. That step only succeeds if the repository has GitHub Pages configured with GitHub Actions as the source (Settings → Pages → Build and deployment → Source). If Pages isn't enabled, the workflow run on master will go red on the deploy step even though the site itself built cleanly.

Worth being precise about what this needs, since it's a common assumption: there's no secret to add for this path. The workflow uses the GitHub-Pages-native actions (configure-pages / upload-pages-artifact / deploy-pages), which authenticate via the workflow's own id-token: write OIDC token plus the built-in GITHUB_TOKEN — both already declared on the deploy job. So no API key, PAT, or deploy key is involved. The single prerequisite is the repository setting above (enabling it also provisions the github-pages environment the job targets). A secret would only come into play if you wanted to publish somewhere other than GitHub Pages (Netlify, Vercel, an internal host, etc.), which would be a different action and a different conversation.

So, a question and a couple of options:

  • Do you want the docs published to GitHub Pages? If yes, the only thing needed is enabling Pages with the GitHub Actions source before (or right at) merge — the workflow already requests the pages: write + id-token: write permissions the deploy needs, and the artifact upload is wired. The site would land at the repository's Pages URL; if you'd want it under a custom domain or a non-default base path, that's a small docs/.vitepress/config change I can fold in here.
  • Not yet / not via Pages? I can make the deploy job dormant so the merge can't produce a red master run — either drop the deploy job entirely (build-only, which still gives the PR-time doc-break gate), or gate it behind a repository variable (e.g. if: vars.DEPLOY_DOCS == 'true') so it stays inert until you flip the switch. Either is a one-commit change in this PR.

Happy to make whichever you prefer here so the merge is clean. If you'd rather sort the Pages setup separately and merge as-is, that works too — just let me know and I'll gate the deploy job so master stays green in the meantime.

@ottobolyos
Copy link
Copy Markdown
Contributor Author

A separate design point on the generated reference pages, since this PR sets the policy and I'd rather raise it than let it set a precedent silently.

The branch treats the two generated doc trees differently: the docfx API pages under docs/api/ are gitignored and regenerated on every build (so the repo never carries a stale copy of the API surface), while the five Roslyn-generated pages under docs/reference/ (http-api, configuration, environment-variables, cli, index) are committed and protected by a build-time drift gate (generate-reference.sh --check) that fails CI if a source change wasn't reflected in a regenerated page.

On reflection I think docs/reference/ would be better off following the same gitignore-and-generate-at-build policy as docs/api/. The reasoning: those pages are derived from the C# itself — XML doc comments, the configuration classes, the HTTP route handlers, the MTCONNECT_* env-var lookups — which change continually. So there's a standing risk that someone edits the code, forgets to regenerate, and the committed pages drift out of date. The drift gate mitigates that, but it's really a band-aid: it turns "silently stale docs" into "a red check that forces a regen commit". Generating at build removes the failure mode entirely — there's nothing committed to go stale, and the cross-OS determinism issue that reddened the earlier Windows run (a CRLF trailing-\r divergence) can't recur, because there's no committed copy to diverge from.

The trade-off is real but modest: you'd lose the PR-diff visibility of a generated page changing, and the pages would no longer be browsable as raw files on GitHub — only on the built site. The source change that caused them is still reviewable.

My lean is to switch docs/reference/ to build-time generation, but it's your call, and either way I'd do it as a small follow-up rather than expanding this PR — so this one can merge on its current footing. If you'd rather keep the committed-and-gated approach, that's perfectly defensible too.

(The same question doesn't apply to the SysML-generated *.g.cs: those derive from the pinned external SysML model rather than from hand-written code, so they only change on a deliberate spec-version bump — committing them is the right call, with a regen drift-check as the natural safety net if one's wanted.)

@ottobolyos ottobolyos changed the title docs: VitePress documentation site docs(docs): add VitePress documentation site May 28, 2026
@ottobolyos ottobolyos changed the title docs(docs): add VitePress documentation site docs: add VitePress documentation site May 28, 2026
@PatrickRitchie PatrickRitchie moved this from In Progress to Reviewing in MTConnect.NET-Development May 29, 2026
@PatrickRitchie PatrickRitchie moved this from Reviewing to Ready to Merge in MTConnect.NET-Development May 31, 2026
@PatrickRitchie PatrickRitchie merged commit 544a331 into TrakHound:master May 31, 2026
7 checks passed
@github-project-automation github-project-automation Bot moved this from Ready to Merge to Done in MTConnect.NET-Development May 31, 2026
@ottobolyos ottobolyos deleted the feat/vitepress-docs branch May 31, 2026 13:58
@PatrickRitchie
Copy link
Copy Markdown
Contributor

After merging into the master branch, the action completed successfully but it looks like some of the links are broken and the css doesn't load. Likely an issue with a base path or something? I'm not sure how GitHub Pages handles paths and relative links.

https://trakhound.github.io/MTConnect.NET

Let me know if there is something I need to configure on my end.

@ottobolyos
Copy link
Copy Markdown
Contributor Author

I’ll look into this. I’ll fix all broken links and add a check for broken internal links (i.e. checking links referencing files/headings within the docs, not links referencing websites/URLs on the Internet).

@ottobolyos
Copy link
Copy Markdown
Contributor Author

ottobolyos commented May 31, 2026

The is actually less about broken links (which there are too) and more about deployment to a /MTConnect.NET subpath, while VitePress config presumes deployment to /.

I’ll create separate PRs to fix the issues: 1.[#179] fix the broken links and prevent them; 2. [#180] add an env var so that we can build the docs to any URL path (e.g. we will use DOCS_BASE=/MTConnect.NET/ in the CI; it would still default to /).

I’ll prioritise #180 so that the deployed docs work as expected.

@ottobolyos
Copy link
Copy Markdown
Contributor Author

ottobolyos commented Jun 1, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants