Split out from #17.
Problem
AnalyzeResult currently carries four parallel collections: StatementLineage.nodes, StatementLineage.edges, GlobalLineage.nodes, GlobalLineage.edges (crates/flowscope-core/src/types/response.rs:82-170, :521-629). Consumers have to reconcile per-statement vs global IDs, and features like multi-file analysis or lazy expansion would need yet another list pair.
Proposal
- Introduce flat
nodes: Vec<Node> and edges: Vec<Edge> at the top level of AnalyzeResult.
- Extend
Node with statementIds: Vec<usize> (and optional sourceName) so statement grouping is derived dynamically.
- Keep
statements: Vec<StatementMeta> for per-statement metadata (type, span, complexity) but drop the embedded graph.
- Fold
GlobalNode/GlobalEdge fields (canonicalName, statementRefs, producerStatement, consumerStatement) into Node/Edge.
EdgeType::CrossStatement stays — assigned at build time when the edge bridges statement groups.
Non-goals
No schema/resolution changes. No UI/TS binding rewrite beyond adapter shims.
Acceptance
- Rust + TS types updated; single source of truth in
response.rs / packages/core/src/types.ts.
- Existing consumers (VS Code extension, app) keep working via a thin adapter during one release cycle.
- JSON snapshot tests updated and
cargo test --workspace green.
Foundational — unblocks downstream graph/navigation/lazy-loading work.
Split out from #17.
Problem
AnalyzeResultcurrently carries four parallel collections:StatementLineage.nodes,StatementLineage.edges,GlobalLineage.nodes,GlobalLineage.edges(crates/flowscope-core/src/types/response.rs:82-170,:521-629). Consumers have to reconcile per-statement vs global IDs, and features like multi-file analysis or lazy expansion would need yet another list pair.Proposal
nodes: Vec<Node>andedges: Vec<Edge>at the top level ofAnalyzeResult.NodewithstatementIds: Vec<usize>(and optionalsourceName) so statement grouping is derived dynamically.statements: Vec<StatementMeta>for per-statement metadata (type, span, complexity) but drop the embedded graph.GlobalNode/GlobalEdgefields (canonicalName,statementRefs,producerStatement,consumerStatement) intoNode/Edge.EdgeType::CrossStatementstays — assigned at build time when the edge bridges statement groups.Non-goals
No schema/resolution changes. No UI/TS binding rewrite beyond adapter shims.
Acceptance
response.rs/packages/core/src/types.ts.cargo test --workspacegreen.Foundational — unblocks downstream graph/navigation/lazy-loading work.