fix(editor): match real F∆I YAML type shape + warn on bad types

The 0.15.0 type-token coloring regex hunted for `type: <name>`,
but the F∆I YAML actually shapes types as `<fieldname>: <name>`
under `inputs:` / `outputs:` blocks. Real-world flows
(`hello.yaml`, `extract.yaml`) and module manifests (echo,
text-summarize, …) never produce the `type:` keyword unless
the operator hand-authors the long form.

Fix the regex to match an indented `KEY: VALUE` line where the
value is one of `text|json|bytes|file|number|integer`. Leading
whitespace is required so top-level keys (`name: foo`,
`version: 0.1.0`) can't false-match. This handles both
shapes — the implicit `pdf: bytes` and the explicit
`type: bytes` (used by module schema v2 inputs lists) —
because either way the pattern boils down to "key colon known
type token".

Analyzer also grows a type-token check: any inputs/outputs
field whose value isn't a known type lights up as a warning
("Unknown input type 'byes' …"), modulo `$ref` expressions
(flow outputs) and empty values (operator is mid-keystroke).

Adds `test/flow_analyzer_test.dart` with seven cases covering
empty, valid hello, unknown capability, unknown type, parse
error, version-bare matching, and the empty-installed-list
silence path.

Bumps the package to 0.15.1.

Signed-off-by: flemming-it <sf@flemming.it>
This commit is contained in:
flemming-it 2026-06-04 02:24:29 +02:00
parent 885d2db4e1
commit 911f368362
4 changed files with 162 additions and 7 deletions

View file

@ -19,6 +19,8 @@
import 'package:flutter_code_editor/flutter_code_editor.dart';
import 'package:yaml/yaml.dart';
import 'wire_colors.dart';
class FlowAnalyzer extends AbstractAnalyzer {
/// Returns the names of capabilities the operator has installed.
/// A closure so the analyzer always sees the current list
@ -84,10 +86,44 @@ class FlowAnalyzer extends AbstractAnalyzer {
}
}
}
// Flag any inputs/outputs declaration whose value isn't a
// recognised type token. Flow YAML keeps each field as a
// `<name>: <type>` pair under `inputs:` / `outputs:` a
// typo like `pdf: byes` should light up rather than fail
// silently at run time.
_checkFieldTypes(doc['inputs'], 'input', issues);
_checkFieldTypes(doc['outputs'], 'output', issues);
}
return AnalysisResult(issues: issues);
}
void _checkFieldTypes(YamlNode? block, String kind, List<Issue> out) {
if (block is! YamlMap) return;
for (final entry in block.nodes.entries) {
final value = entry.value.value;
if (value is! String) continue;
// Skip reference expressions like `$inputs.name` or
// `$step.field` only flow `outputs:` use these and they
// aren't type declarations.
if (value.startsWith(r'$')) continue;
// Skip plainly empty values the operator is typing, not
// declaring a typo.
if (value.trim().isEmpty) continue;
if (!kKnownTypes.contains(value)) {
out.add(
Issue(
line: entry.value.span.start.line,
message:
'Unknown $kind type "$value". '
'Use one of: ${kKnownTypes.join(", ")}.',
type: IssueType.warning,
),
);
}
}
}
}
/// Strip the `@<version>` tail from a capability spec so