Skip to content

feat: add implicit scoped views#2648

Merged
davydkov merged 5 commits intomainfrom
davydkov/implicit-scoped-views
Feb 21, 2026
Merged

feat: add implicit scoped views#2648
davydkov merged 5 commits intomainfrom
davydkov/implicit-scoped-views

Conversation

@davydkov
Copy link
Copy Markdown
Member

@davydkov davydkov commented Feb 21, 2026

Summary

Auto-generate scoped views for all elements without explicit views, enabling drill-down navigation out of the box. Implicit views are grouped under an "Auto" folder in the view sidebar and can be disabled via the implicitViews config option (enabled by default).

Changes

  • Implicit views have view IDs prefixed with __ (e.g., __system_backend) and titles prefixed with Auto / to organize them in the sidebar
  • Navigation works automatically via the existing assignNavigateTo system — clicking an element navigates to its implicit scoped view
  • Configurable via implicitViews: false in project config (defaults to true)
  • Documented in config guide with examples
  • Schema updated for IDE autocomplete support

Testing

All 869 tests pass. Updated snapshots and test assertions to reflect new implicit views in models.

Co-Authored-By: Claude Opus 4.6 [email protected]

Summary by CodeRabbit

  • New Features

    • Automatic scoped view generation for elements without explicit views is enabled by default; configurable via a new implicitViews project setting.
  • Documentation

    • Added docs explaining implicit views and how to disable them via configuration with examples.
  • Tests

    • Updated and added tests to reflect implicit view creation and adjusted expectations for view/diagram counts.

Auto-generate scoped views for all elements without explicit views, enabling drill-down navigation out of the box. Implicit views are placed under an "Auto" folder in the view sidebar and can be disabled via the `implicitViews` config option (enabled by default).

- Implicit views have view ID prefixed with `__` and title prefixed with `Auto /`
- Navigation works automatically via existing `assignNavigateTo` system
- Configurable via `implicitViews` boolean in project config (defaults to true)
- Updated JSON schema for editor autocomplete
- Added configuration documentation

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 21, 2026

🦋 Changeset detected

Latest commit: c4e2b4f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 19 packages
Name Type
@likec4/language-server Patch
@likec4/config Patch
@likec4/playground Patch
@likec4/language-services Patch
likec4 Patch
@likec4/mcp Patch
@likec4/vite-plugin Patch
likec4-vscode Patch
@likec4/docs-astro Patch
@likec4/style-preset Patch
@likec4/styles Patch
@likec4/core Patch
@likec4/diagram Patch
@likec4/generators Patch
@likec4/layouts Patch
@likec4/log Patch
@likec4/react Patch
@likec4/tsconfig Patch
@likec4/vscode-preview Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 21, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Adds configurable implicit scoped views: a new implicitViews project config flag and schema, model-builder logic to auto-create scoped views for elements without explicit views (unless disabled), updated docs and tests, minor vite alias change, and a changeset.

Changes

Cohort / File(s) Summary
Configuration & Schemas
packages/config/src/schema.ts, schemas/likec4-config.schema.json, e2e/src/issue-2282/.likec4rc, e2e/src/likec4/likec4.config.ts
Adds optional boolean implicitViews to the project config schema and JSON schema; updates example/configs to set implicitViews: false in e2e fixtures.
Model Builder
packages/language-server/src/model/builder/buildModel.ts
When project.config.implicitViews is not false, generates implicit scoped views for non-global elements lacking explicit views (auto-generated IDs/titles, wildcard rule), avoiding duplicate IDs.
Tests & Test Setup
packages/language-server/src/model/__tests__/model-builder.spec.ts, packages/language-server/src/model/__tests__/model-builder-view-folders.spec.ts, packages/language-server/src/test/testServices.ts, packages/likec4/src/drawio-tutorial-export-import.spec.ts
Updates test service creation to pass projectConfig (including implicitViews), adjusts expectations for additional implicit views and folder ordering, and makes diagram lookup/assertions more robust.
Documentation
apps/docs/src/content/docs/dsl/Config/index.mdx
Adds documentation describing implicit scoped views and shows how to disable them with implicitViews: false.
Misc / Build / Release
packages/likec4/src/vite/aliases.ts, .changeset/implicit-scoped-views.md
Adds likec4/react Vite alias and a changeset documenting the implicit scoped views feature.

Sequence Diagram(s)

(Skipped)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nibble bytes and hop through trees of code,
Implicit doors appear where views once strode.
Auto folders spring, IDs tucked away,
I guide the drills where explorers play. 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description provides a comprehensive summary with clear sections on changes, testing status, and configuration options. However, it does not follow the provided checklist template for contribution guidelines and commit verification. Consider using the repository's PR description template to include the checklist items (contribution guidelines, rebasing, commit messages, tests, documentation updates) for consistency with repository standards.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add implicit scoped views' clearly and concisely summarizes the main change, which is the introduction of implicit scoped views feature following conventional commit format.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch davydkov/implicit-scoped-views

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/docs/src/content/docs/dsl/Config/index.mdx (1)

182-194: Consider documenting the "Auto" folder name and __ view-ID prefix convention.

The PR description notes that implicit views receive an Auto / title prefix (appearing under an Auto folder in the sidebar) and that their IDs are prefixed with __. Users who title an explicit view Auto / ... or choose an ID starting with __ will silently land in the auto-generated folder / conflict with implicit IDs. A brief note in this section would prevent that confusion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/docs/src/content/docs/dsl/Config/index.mdx` around lines 182 - 194, Add
a short note to the "Implicit views" section documenting the naming convention
so users don’t accidentally collide with auto-generated views: state that
implicit views are shown under an "Auto" folder (title prefixed with "Auto /")
and their view IDs are prefixed with "__", and warn authors not to create
explicit views with titles starting with "Auto /" or IDs starting with "__" (or
recommend choosing a different prefix) to avoid silent conflicts; update the
text near the "Implicit views" heading and the example config to mention this
convention.
packages/language-server/src/model/builder/buildModel.ts (1)

322-361: Missing test for implicitViews: false config opt-out

The feature flag project.config.implicitViews !== false is exercised by the existing tests only in its enabled (default) state. There is no test that sets implicitViews: false on the project config and verifies that no __-prefixed views are generated. Without it, a regression that ignores the flag would go undetected. Based on learnings, "Aim to cover new features with relevant tests and keep test names descriptive."

I can draft a createTestServices-based test case that validates implicitViews: false suppresses all implicit view generation — would you like me to open an issue or add it directly?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/language-server/src/model/builder/buildModel.ts` around lines 322 -
361, Add a test that verifies the implicit view opt-out by setting
project.config.implicitViews = false and asserting that no auto-generated
element views (IDs prefixed with "__" created in the buildModel logic that
pushes into parsedViews) are produced; specifically, use the existing test
helper (createTestServices) to build a model with elements that would normally
generate implicit views, run the code path that calls the buildModel logic (so
parsedViews and elements are populated), and assert parsedViews contains no
entries whose id equals the computed viewId pattern ('__' + fqn.replaceAll('.',
'_')) or simply startsWith("__"); reference the same symbols used in the diff
(project.config.implicitViews, parsedViews, elements, keys(), isGlobalFqn,
viewId) so the test targets the exact feature gate and prevents regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/language-server/src/model/builder/buildModel.ts`:
- Around line 330-341: existingViewIds is built once from parsedViews and never
updated, so when you generate synthetic viewId (const viewId = ('__' +
fqn.replaceAll('.', '_')) as ViewId) you may allow duplicates to be added to
parsedViews and later overwritten by indexBy(prop('id')). Fix: after you push a
new view into parsedViews (the synthetic view created for FQNs not in
elementsWithExplicitViews and not isGlobalFqn), immediately add viewId to
existingViewIds (existingViewIds.add(viewId)) so subsequent iterations detect
the collision and skip or handle it; keep the existing guards
(elementsWithExplicitViews, isGlobalFqn) and the viewId normalization logic
unchanged.

---

Nitpick comments:
In `@apps/docs/src/content/docs/dsl/Config/index.mdx`:
- Around line 182-194: Add a short note to the "Implicit views" section
documenting the naming convention so users don’t accidentally collide with
auto-generated views: state that implicit views are shown under an "Auto" folder
(title prefixed with "Auto /") and their view IDs are prefixed with "__", and
warn authors not to create explicit views with titles starting with "Auto /" or
IDs starting with "__" (or recommend choosing a different prefix) to avoid
silent conflicts; update the text near the "Implicit views" heading and the
example config to mention this convention.

In `@packages/language-server/src/model/builder/buildModel.ts`:
- Around line 322-361: Add a test that verifies the implicit view opt-out by
setting project.config.implicitViews = false and asserting that no
auto-generated element views (IDs prefixed with "__" created in the buildModel
logic that pushes into parsedViews) are produced; specifically, use the existing
test helper (createTestServices) to build a model with elements that would
normally generate implicit views, run the code path that calls the buildModel
logic (so parsedViews and elements are populated), and assert parsedViews
contains no entries whose id equals the computed viewId pattern ('__' +
fqn.replaceAll('.', '_')) or simply startsWith("__"); reference the same symbols
used in the diff (project.config.implicitViews, parsedViews, elements, keys(),
isGlobalFqn, viewId) so the test targets the exact feature gate and prevents
regressions.

Update view count assertions in drawio-tutorial-export-import.spec.ts
to account for auto-generated implicit scoped views.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/likec4/src/drawio-tutorial-export-import.spec.ts (1)

138-143: Consider adding at least one assertion on an implicit view to guard the new feature.

The for-loop only checks structural validity (<mxGraphModel) for all diagrams, and the two explicit views get content assertions — but none of the three new implicit views are individually verified. A minimal check like the one below would provide a regression guard for the feature being introduced:

✨ Suggested addition
  expect(indexDiagram!.content).toContain('Customer')
  expect(saasDiagram!.content).toContain('Frontend')
  expect(saasDiagram!.content).toContain('Backend')
+
+  // Verify at least one implicit view is present and has content
+  const customerImplicitDiagram = diagrams.find(d => d.id === 'likec4-__customer')
+  expect(customerImplicitDiagram).toBeDefined()
+  expect(customerImplicitDiagram!.content).toContain('Customer')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/likec4/src/drawio-tutorial-export-import.spec.ts` around lines 138 -
143, The tests currently validate that each entry in diagrams contains
'<mxGraphModel' and check indexDiagram and saasDiagram contents, but they don't
assert any of the three new implicit views individually; update the spec to
locate at least one implicit view from the diagrams collection (e.g., by name or
id) and add an assertion that its .content contains an expected token (for
example a view-specific label like 'ImplicitViewName' or another domain string),
referencing the existing variables diagrams, indexDiagram, and saasDiagram to
find and assert the implicit view content to guard the new feature.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/likec4/src/drawio-tutorial-export-import.spec.ts`:
- Around line 138-143: The tests currently validate that each entry in diagrams
contains '<mxGraphModel' and check indexDiagram and saasDiagram contents, but
they don't assert any of the three new implicit views individually; update the
spec to locate at least one implicit view from the diagrams collection (e.g., by
name or id) and add an assertion that its .content contains an expected token
(for example a view-specific label like 'ImplicitViewName' or another domain
string), referencing the existing variables diagrams, indexDiagram, and
saasDiagram to find and assert the implicit view content to guard the new
feature.

When projectConfig is provided to createTestServices, implicitViews
defaults to false. View-folder tests explicitly opt out with
projectConfig: {}. Two new tests verify implicit views behavior
when explicitly enabled.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/language-server/src/model/__tests__/model-builder-view-folders.spec.ts (1)

178-202: Consider also asserting that __sys2 is placed in the Auto folder.

The current assertions are sufficient to verify the skip logic, but the test doesn't confirm that the generated __sys2 ends up inside the Auto folder rather than at the root. Switching to buildLikeC4Model() and adding a folder-placement check would make this test parallel in depth to the first new test:

♻️ Optional extension
-    const model = await buildModel()
-    // sys1 has an explicit scoped view, so no implicit view for it
-    // sys2 gets an implicit view __sys2
-    expect(keys(model.views)).toContain('__sys2')
-    expect(keys(model.views)).not.toContain('__sys1')
+    const model = await buildLikeC4Model()
+    // sys1 has an explicit scoped view, so no implicit view for it
+    // sys2 gets an implicit view __sys2
+    expect(keys(model.$data.views)).toContain('__sys2')
+    expect(keys(model.$data.views)).not.toContain('__sys1')
+    // __sys2 should be placed in the Auto folder
+    expect([...model.viewFolder('Auto').views]).toEqual([model.view('__sys2')])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/language-server/src/model/__tests__/model-builder-view-folders.spec.ts`
around lines 178 - 202, Update the test to also verify that the implicit view
__sys2 is placed inside the Auto folder: instead of only calling buildModel(),
call buildLikeC4Model() (or otherwise obtain foldered output) and then assert
that model.views['__sys2'] (or the view entry found via keys(model.views)) has
its folder set to 'Auto' (or that the Auto folder contains '__sys2'); keep the
existing checks for presence/absence of __sys2 and __sys1 and add this single
folder-placement assertion referencing buildLikeC4Model and model.views/__sys2.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/language-server/src/model/__tests__/model-builder-view-folders.spec.ts`:
- Around line 178-202: Update the test to also verify that the implicit view
__sys2 is placed inside the Auto folder: instead of only calling buildModel(),
call buildLikeC4Model() (or otherwise obtain foldered output) and then assert
that model.views['__sys2'] (or the view entry found via keys(model.views)) has
its folder set to 'Auto' (or that the Auto folder contains '__sys2'); keep the
existing checks for presence/absence of __sys2 and __sys1 and add this single
folder-placement assertion referencing buildLikeC4Model and model.views/__sys2.

davydkov and others added 2 commits February 21, 2026 16:38
Update existingViewIds set after generating each implicit view so
that FQNs producing the same viewId (e.g. a.b_c and a_b.c both
mapping to __a_b_c) don't result in duplicate entries.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add implicitViews: false to e2e project configs to prevent
auto-generated views from breaking screenshot snapshots and
expected view ID lists.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@davydkov davydkov merged commit 5ce02f8 into main Feb 21, 2026
15 checks passed
@davydkov davydkov deleted the davydkov/implicit-scoped-views branch February 21, 2026 15:58
@likec4-ci likec4-ci bot mentioned this pull request Feb 21, 2026
@coderabbitai coderabbitai bot mentioned this pull request Mar 6, 2026
5 tasks
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