Replace raw-JSON text inputs with rich UI: script parameter/return types use
a JSON Schema builder (SchemaBuilder + JsonSchemaShapeParser, with a migration
to convert existing definitions); alarm trigger config uses a type-aware
editor with a flattened attribute picker (AlarmTriggerEditor). AlarmActor
gains optional direction (rising/falling/either) on RateOfChange triggers.
Three more editor features rolled in:
1. Roslyn Format command.
New POST /api/script-analysis/format runs Formatter.Format() from
Microsoft.CodeAnalysis.CSharp.Workspaces on the parsed script
tree. monaco-init.js registers a DocumentFormattingEditProvider
so Ctrl/Cmd-Shift-F and the toolbar "Format" button both work.
2. Inlay hints with parameter names.
New POST /api/script-analysis/inlay-hints walks CallShared /
CallScript invocations and emits InlayHint records positioned at
each argument with the matching parameter's name (e.g. "name:").
Ghost text appears via Monaco's InlayHintsProvider.
3. SCADA005 argument-type diagnostic.
Literal type vs. declared parameter type check on every
CallShared/CallScript argument. Float accepts Integer literals;
Object/List accept anything; null only matches reference-ish
types. Legacy lowercase types ("string" etc) from the DB are
normalized to the canonical set before comparison so existing
data doesn't false-negative. Non-literal args (variables,
expressions) are skipped — out of scope for a cheap pass.
4. Parameters["name"] hover.
Hover endpoint now also resolves Parameters["X"] element-access
keys against the form's DeclaredParameterShapes and returns
"parameter `name: String`"-style markdown. MonacoEditor surfaces
the new DeclaredParameterShapes parameter; ScriptParameterNames
gets a ParseShapes companion.
5. Problems panel.
Bootstrap card under the editor listing every marker with
severity badge, line number, message, and SCADA / CS code. Click
a row to scroll the editor to that line and focus. JS now
invokes OnMarkersChanged on the .NET side whenever
setModelMarkers fires, so the panel stays in sync with the
editor.
6. Editor toolbar.
Small top-right strip on each editor with Format / Wrap /
Minimap / Theme toggles. New MonacoBlazor.format,
setEditorOption, and revealLine JS APIs back the buttons and the
problems-panel scroll-to-line.
Contracts:
- FormatRequest / FormatResponse
- InlayHintsRequest / InlayHintsResponse / InlayHint
- HoverRequest.DeclaredParameters
- MonacoEditor.DeclaredParameterShapes parameter
- MonacoEditor.MarkersChanged callback
- ScadaContext.DeclaredParameterShapes
10 new xUnit tests covering format, inlay hints, SCADA005 (string-
expects-integer, integer-expects-string, float-accepts-integer,
object-accepts-anything, non-literal-skipped), and Parameters key
hover. Total: 139 -> 149.
Microsoft.CodeAnalysis.CSharp.Workspaces 4.13.0 added to pull in
Formatter and AdhocWorkspace.
Browser-verified: typing `CallShared("Greet", 42)` now shows the
"name:" inlay hint and a SCADA005 squiggle on `42`; Parameters["typo"]
shows SCADA003 as before; the toolbar buttons all work.
Adds Microsoft.CodeAnalysis.CSharp.Scripting (4.13.0). Scripts are
compiled as C# script fragments against a ScriptHost globals type
that mirrors what the runtime exposes (Parameters bag, CallShared,
CallScript) — Roslyn reads the signatures so those identifiers are
in scope for analysis without executing anything.
ScriptAnalysisService:
- Diagnose(code): Compilation.GetDiagnostics() projected to
Monaco-shaped DiagnosticMarker records (severity 8/4/2/1).
- Complete(code, line, col): dot-member lookup via SemanticModel
when the token at position is part of a MemberAccessExpression;
falls back to LookupSymbols at position for the general case.
Two endpoints exposed by the existing CentralUI endpoint pipeline,
both behind RequireDesign policy:
POST /api/script-analysis/diagnostics
POST /api/script-analysis/completions
monaco-init.js registers a csharp CompletionItemProvider with dot/
paren/quote trigger chars, plus a 500 ms debounced diagnostics pass
on every keystroke that pushes markers via setModelMarkers. Initial
pass fires on editor create so existing scripts surface errors right
away. Auth uses the existing cookie via credentials: same-origin.
Smoke-verified:
- Typing `DateTimeOffset.UtcNow` (no semicolon) shows the missing
semicolon squiggle in real time.
- Ctrl-Space at file scope returns the full type universe
(AccessViolationException, Action, Akka, AppDomain, ...).
Wave 2 of three. SCADA-specific extensions (declared param keys,
shared/sibling script names, forbidden-API diagnostic) follow.
- WP-0.10: Role-based Host startup (Central=WebApplication, Site=generic Host),
15 component AddXxx() extension methods, MapCentralUI/MapInboundAPI stubs
- WP-0.11: 12 per-component options classes with config binding
- WP-0.12: Sample appsettings for central and site topologies
- Add execution procedure and checklist template to generate_plans.md
- Add phase-0-checklist.md for execution tracking
- Resolve all 21 open questions from plan generation
- Update IDataConnection with batch ops and IAsyncDisposable
57 tests pass, zero warnings.
17 source projects (Commons + Host + 15 components) and 17 xUnit test projects.
SLNX format, net10.0, nullable enabled, warnings as errors. All components
reference Commons; Host references all components. Builds and tests clean.