Skip to content

feat(documents): read OpenSysML-generated documents next to named views - #39

Open
devin-ai-integration[bot] wants to merge 5 commits into
developfrom
feature/document-tool
Open

devin-ai-integration[bot] wants to merge 5 commits into
developfrom
feature/document-tool

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Change

A project can now open and read the documents the embedded OpenSysML engine generates, next to its named views. Source stays authoritative; the surface is read-only.

  • Engine overlay studio_render_document_v1 (engine-bridge/opensysml/render_document.go → engine studio_document.go): ListDocuments {modelHash} resolves part def specializations of DocumentQueries::Document through docplan.IsDocumentDefinition with their declaring origins; RenderDocument {modelHash, document, form} runs docplan.Compile → docir.EvaluateLinked (sibling plans, runtime query context) → docrender.HTML/Markdown and returns a versioned envelope: content, references (every data-element qualified name with its origin), contents (every data-name block path with its declaring part and embedded view) and diagnostics typed by stage (planning/evaluation/rendering) and kind (unknownQuery, missingBinding, bindingType, missingViewSource, …) with file/line. Field names mirror the upstream RenderDocument protojson (modelHash, document, form) so the local bridge can be swapped for the RPC later. validated_document.go (combined) refuses revisions with validation errors before planning, like the view bridge. Graphviz is unavailable in wasm; HTML requests the DOT diagram form because the Mermaid HTML path calls os.Getwd (unimplemented on js); Markdown keeps Mermaid fences. The browser never shows either: every sysml-diagram figure is replaced by the native renderer or a notice.
  • Worker/adapter: ModelSnapshot.documents (optional) is listed during parse; new document worker operation; createSemanticEngine implements DocumentEngine.renderDocument with stale-hash rejection in the worker and validateRenderedDocument on reply.
  • Workspace (workspace/documents, framework/engine independent): rendered-document TypeBox contract, documentEntries (Explorer grouping), documentSourceTarget (UTF‑8 origin → UTF‑16 editor range in the exact applied file, with explained library/draft/unknown cases), documentDiagnostics. createWorkspace gains renderedDocument state, openDocument, closeDocument and the non-publishing previewView used by embedded diagrams; document diagnostics join the revision's diagnostics so Issues navigation works unchanged.
  • Workbench: Explorer Documents group (name, declaring file, qualified-name title; a hint when the project declares none); Document tab beside Diagram/Requirements/Matrix; DocumentPane rebuilds the engine HTML through an allowlist (document-html.ts: no scripts, styles, media, forms, event handlers or non-sysml- classes; data-* attributes and ids kept) and delegates clicks: data-element → element declaration, headings/paragraphs/blocks → their data-name path in the document definition, reusing setFile/setFocusRange/selection. figure.sysml-diagram[data-view] blocks mount Diagram in a new embedded mode (no header, read-only) with Open as named view; undrawable/undeclared views show the engine's notice/diagnostics. Documents re-render after apply/undo/redo together with the open view, showing a "Re-rendering document" status meanwhile; a pane is never left blank on failure (typed diagnostics are shown and listed in Issues).
  • Example/docs: examples/inspection-rover/report.sysml (RoverReport::InspectionReport: a section per subsystem with a query-backed parts table, a requirements table, a Diagram block embedding RoverViews::architecture, an inline Ref); catalog/index/README updated (seven files). README, docs/capabilities.md, docs/architecture/README.md, docs/next-steps.md (follow-ups: inline text editing via Toolkit transactions, PDF export, Flexo publication, upstream RPC swap) and engine-bridge/README.md provenance.
  • Visual baselines: 48 captures regenerated from this PR's own CI runs (baseline-compatible runner); each differs only by the Explorer's Documents group, the Document tab, report.sysml and the seven-file status.

Rover report with the embedded architecture view

Evidence

Node 26.3.1, Go 1.27.3 (prepared under sandbox/opensysml-012).

$ go test ./internal/frontend/combined ./internal/frontend/engine   # via npm run engines:prepare
ok   github.com/Open-MBEE/OpenSysML/internal/frontend/combined 5.498s
?    github.com/Open-MBEE/OpenSysML/internal/frontend/engine [no test files]
Prepared OpenSysML with the validated native-view bridge.

New bridge tests: TestStudioListDocuments, TestStudioRenderDocumentHTML, TestStudioRenderDocumentMarkdown, TestStudioRenderDocumentUnknown (unknown document, unknown form, stale model, non-document), TestStudioRenderDocumentPlanningError (validation gate + typed missingQuery with file/line), TestStudioRenderDocumentInvalidModel. gofmt -l engine-bridge/opensysml/ empty.

$ npm run check          # prettier, architecture, tsc, vitest, script tests
 Test Files  24 passed (24)
      Tests  171 passed (171)
ℹ pass 10  ℹ fail 0
EXIT 0

New unit tests: src/lib/workspace/documents/documents.test.ts (explorer grouping, click-to-source mapping incl. UTF‑8/UTF‑16 offsets and refusal cases, envelope validation, typed diagnostics).

$ npm run build           # engines:prepare + tsc + vite build (also run by Playwright's webServer)
$ npm run test:e2e -- --project=functional documents.spec.ts rover.spec.ts shell-entry.spec.ts
  16 passed (2.3m)
$ npm run test:e2e -- --project=functional --grep @critical     # CI: 18 passed (4.4m), every run

tests/e2e/documents.spec.ts (@critical): opens the rover report through the real engine, checks the article's data-document, an Energy heading, the battery/RoverComponents::Battery and requirement documentation table cells, that no script/style/img/iframe or diagram fences survive, that the embedded RoverViews::architecture block is data-state="rendered" with the native part battery : Battery group and Open as named view, clicks the inline rover reference and asserts the source selection part rover : InspectionRover; in system.sysml, a row click (part battery : Battery;), a heading click (the mobility : Section declaration in report.sysml), and the named-view handoff. The second scenario applies a title change and sees the re-rendered heading, then removes a table's query and asserts the typed references no query issue with a report.sysml line link while the last document is retained. rover.spec.ts/shell-entry.spec.ts file-count assertions updated 6 → 7.

$ npm run test:e2e -- --project=visual     # CI, head 3a48608: 88 passed, 1 failed

Baselines: the first CI run failed 34 comparisons; because several scenarios capture more than one screenshot, three further runs exposed 14 second/third captures. Every failing comparison was inspected from the CI artifacts (*-diff.png): the differences are the new Documents group (shifting Views/Model), the Document tab, report.sysml and "7 files"; no diagram, dialog or form pixels changed. The CI -actual.png captures were committed as the new baselines (local Linux fonts on the development VM differ from the runner's — even the untouched landing page shows 15 px of drift there — so none were generated locally).

Remaining failure on the latest run: requirement hierarchy and declared satisfaction in dark at 768 (requirements-dark-768.png, 1,849 px). The light variant of the same capture failed on the previous run and both passed on the two runs before with identical application code (those runs differ only by PNG baselines). The diff is a sub-pixel shift of the whole requirement diagram after centerRequirementCard's real middle-button drag, i.e. a pre-existing capture race in that scenario, so that baseline was deliberately left unchanged rather than re-recorded.

Manual/agent UI run against the production build with the real pinned engines: report/table rendering, exact source reveal by reference, row, heading and paragraph, Tab/Enter on a reference, native embedded diagram and named-view handoff, title apply/undo/redo, missing-query rejection with retained report and Issues navigation (report.sysml:60), exact draft discard, busy-state tab disabling, HTML-like source text rendered inert, 1440/768 px in light and dark.

Light Dark
Report in light Report in dark

Not covered: Firefox/WebKit; hostile engine responses beyond the allowlist unit tests (the browser check used HTML-like source text through the real engine).

Compatibility

  • Source/model/view: no change to parsing, named views, exposure or filters. The rover example gains report.sysml (bundle now seven files).
  • Saved format: unchanged (version 1); ModelSnapshot.documents is an optional runtime field, not persisted.
  • Dependencies: none added (HTML is rebuilt through the DOM allowlist, no markdown/HTML library).
  • Engine profile: pins and checksums unchanged; new overlay files and dispatch seams in scripts/prepare-opensysml.mjs change the recorded patchHash; capability studio_render_document_v1 added. Planning errors the pinned checks also report as model diagnostics are gated before rendering, so a document with such an error makes the revision invalid for views as well (existing behavior).
  • Known limits (documented): read-only, no inline text editing, no publication/Flexo, no PDF/AsciiDoc in the browser; documents re-render on apply, not while typing.

Link to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/386f45b0cec7434dbd9f894844bd8efd
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/386f45b0cec7434dbd9f894844bd8efd?variant=devin
Requested by: @HuiJun

Add the studio_render_document_v1 overlay (ListDocuments/RenderDocument over docplan, docir and docrender) to the pinned OpenSysML wasm, list document definitions in the Explorer, render the engine HTML read-only in a sanitized Document pane with click-to-source, mount native view renderers for Diagram blocks, re-render on apply, surface typed planning/evaluation failures in Issues, and add the inspection-rover report with docs and tests.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration Bot and others added 4 commits November 11, 2026 22:47
Regenerated on the CI runner (baseline-compatible fonts) from the PR's visual run: every changed capture differs only by the Explorer's Documents group, the Document representation tab, report.sysml and the seven-file status in the inspection-rover project.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
… renders

After apply, undo or redo the Document pane announced the chooser hint until the engine returned the re-rendered document. The pane now shows a status message naming the document being re-rendered instead.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…group

The requirement hierarchy, model exploration, assembly exploration and rover guided scenarios capture more than one screenshot; the earlier run stopped at their first. These captures come from the CI runner and differ only by the Explorer's Documents group, the Document tab and report.sysml.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
…ocuments group

Third capture of the rover guided scenario, taken from the CI runner; it differs only by the Explorer's Documents group, the Document tab and report.sysml.

Co-Authored-By: jason.han <hanhuijun@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant