Skip to content

fix(vscode): build relationships that name the nodes the picker built - #3113

Merged
YoofiTT96 merged 12 commits into
finos:mainfrom
YoofiTT96:feat/2859-vscode-picker-items
Oct 2, 2026
Merged

YoofiTT96 merged 12 commits into
finos:mainfrom
YoofiTT96:feat/2859-vscode-picker-items

Conversation

@YoofiTT96

@YoofiTT96 YoofiTT96 commented Sep 15, 2026 •

Copy link
Copy Markdown
Member

Description

The VS Code pattern picker builds an architecture from a pattern. It writes that architecture into the author's file.

A pattern can offer a choice. The picker read the node list and the relationship list separately. It took the first alternative of each list. Nothing connected the two choices. The picker could therefore build a relationship that names a node it did not build.

The canvas cannot draw that link. "Apply Pattern" merges the broken relationship into the architecture that the author has open.

Fixes #3196.

What changed

The picker now takes the relationship alternative whose endpoints it built. If no alternative fits, it takes the first one. A position is therefore never empty.

The picker also skips an alternative that it cannot build, such as a bare $ref. Before this change, that case gave no nodes. The relationships that name those nodes were still built.

This PR no longer adds items support

This PR was the fifth in the #2859 stack. It added catalogue reading to the picker.

The review showed a problem. The picker chooses a catalogue node and a catalogue relationship independently. That is what makes the broken link.

PATTERN-DECISIONS.md decides this differently. A catalogue is what an architecture may add. calm generate builds no member that a decision does not name. The picker now keeps the same rule and builds nothing from a catalogue. It therefore agrees with the CLI.

The picker leaves the scope of #2859. The other four PRs cover items for validation, generation, the pattern diagram and the diff.

The defect is older than this PR

main makes the same broken reference through prefixItems alternatives. The fix acts on the choice, not on one declaration site. It therefore covers both sites.

Still open

No document records the purpose of the picker. The picker writes to the author's file, as calm generate does. calm generate asks which alternative the author wants, through --option-choices. The picker does not ask.

#2869 does not mention patterns. The description of #2912 does not mention the picker. No documentation mentions it. A maintainer should decide this before the picker becomes larger.

A pattern can offer no coherent combination. Such a pattern still gives a broken reference. That is a defect in the pattern, not in the picker.

Why the function moves out of the JSX

vitest.config.ts sets environment: 'node'. The package therefore cannot render a React component in a test. instantiateFromPattern was private to PatternPicker.tsx. It moves to pattern-instantiation.ts. This matches the BuildingBlockCreator.tsx and building-block-doc.ts pair beside it.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🎨 Code style/formatting changes
  • ♻️ Refactoring (no functional changes)
  • ⚡ Performance improvements
  • ✅ Test additions or updates
  • 🔧 Chore (maintenance, dependencies, CI, etc.)

Affected Components

  • CLI (cli/)
  • Schema (calm/)
  • CALM AI (calm-ai/)
  • CALM Hub (calm-hub/)
  • CALM Hub UI (calm-hub-ui/)
  • CALM Server (calm-server/)
  • CALM Widgets (calm-widgets/)
  • Documentation (docs/)
  • Shared (shared/)
  • VS Code Extension (calm-plugins/vscode/)
  • Dependencies
  • CI/CD

Testing

  • I have tested my changes locally
  • I have added/updated unit tests
  • All existing tests pass

166 tests pass. There are no lint errors. The extension builds.

Each part of the fix fails a test when it is reverted:

  • the endpoint preference is ignored
  • an alternative that cannot be built is kept
  • catalogues are read again
  • deployed-in, interacts and composed-of are removed from the endpoints that are read

A pattern that offers no choice gives the same result as before. calm/getting-started/conference-signup.pattern.json gives the same 164 lines. The fix acts only where a pattern offers alternatives.

Checklist

  • My commits follow the conventional commit format
  • I have updated documentation if necessary
  • I have added tests for my changes (if applicable)
  • My changes follow the project's coding standards

🤖 Generated with Claude Code

@github-actions github-actions Bot added cli Affects `cli` code shared calm-hub-ui Affects `calm-hub-ui` labels Sep 15, 2026
@YoofiTT96
YoofiTT96 marked this pull request as ready for review September 18, 2026 11:11
@YoofiTT96
YoofiTT96 requested a review from a team as a code owner September 18, 2026 11:11
function declarations(field: any): any[] {
const catalogue = field?.items;
const offersChoice = catalogue?.oneOf?.length || catalogue?.anyOf?.length;
return [...(field?.prefixItems ?? []), ...(offersChoice ? [catalogue] : [])];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The picker takes a node from the node catalogue and a relationship from the relationship catalogue separately. The relationship it adds can point to a node it did not add.

Example: a pattern lists cache then queue in its node catalogue, and gateway-connects-queue then gateway-connects-cache in its relationship catalogue. The picker adds the node cache and the relationship gateway-connects-queue, which points to queue. That node does not exist. The same happens when the first node member is only a $ref, because the picker drops that member.

Result: the canvas cannot draw that link, and the next save drops the relationship with no message to the author.

This is new in this PR: before, the picker did not read catalogues. calm generate avoids it because it takes catalogue members only from a decision that names the node and its relationships together.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed, and the PR has changed shape because of it.

One correction: it is not new here. main produces the same dangling reference through prefixItems. Running main's own instantiateFromPattern over a node entry offering cache or queue and a relationship entry offering gateway-connects-queue or gateway-connects-cache:

nodes:         gateway, cache
relationships: gateway-connects-queue
it names:      gateway, queue

This PR added a second site for the same fault rather than the fault.

Two changes, in 8766545:

The picker now takes the relationship alternative whose endpoints it built, falling back to the first when none fit. It also skips an alternative it cannot build, such as a bare $ref, instead of taking it and discarding the result — that case yielded no nodes at all while the relationships were still built.

The catalogue reading is gone. PATTERN-DECISIONS.md says a catalogue is what an architecture may add and that calm generate builds no member a decision does not name, so the picker holds the same line. That removes the feature this PR was opened for, so it is now a fix and no longer part of #2859.

The defect is tracked as #3196, since it is reachable on main today.

One thing your comment points at that I have not decided here: what the picker is for. It writes to the author's file like calm generate, but calm generate asks which alternative through --option-choices and the picker does not. Nothing records which it is meant to be — #2869 does not mention patterns, #2912's description does not mention it, and it appears in no documentation. Worth your view before the picker grows any further.

YoofiTT96 and others added 2 commits October 1, 2026 05:49
The picker read the node list and the relationship list separately and took
the first alternative of each, so it could build a relationship naming a node
it had not built. The canvas cannot draw that link, and Apply Pattern merges
it into the architecture the author already has open.

It now takes the relationship alternative whose endpoints it built, falling
back to the first when none fit. It also skips an alternative it cannot build,
such as a bare $ref, which previously left the position empty while the
relationships naming it were still built.

Reading items catalogues is dropped. PATTERN-DECISIONS.md records a catalogue
as what an architecture may add, and calm generate builds no member a decision
does not name.
@YoofiTT96 YoofiTT96 changed the title feat(vscode): instantiate items catalogues in the pattern picker fix(vscode): build relationships that name the nodes the picker built Oct 1, 2026
@YoofiTT96
YoofiTT96 merged commit 431e853 into finos:main Oct 2, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

calm-hub-ui Affects `calm-hub-ui` cli Affects `cli` code shared

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VS Code pattern picker builds relationships that point at nodes it did not build

2 participants