feat: add LikeC4 DSL skill with references#2782
Conversation
🦋 Changeset detectedLatest commit: e116d90 The changes in this PR will be included in the next version bump. This PR includes changesets to release 20 packages
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 |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis pull request introduces a new LikeC4 DSL skill for Astro documentation integration, including comprehensive skill documentation, Astro integration setup, and targeted updates to language services error handling and CLI environment detection. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (8)
skills/likec4-dsl/references/configuration.md (2)
166-170: Clarifyextendsexamples presentation.Having two separate JSON objects on consecutive lines without explanation may confuse readers. Consider clarifying these are alternative examples.
📝 Suggested improvement
### `extends` Inherit styles from other config files (JSON only). Single path or array. +Single path: + ```json { "extends": "../shared/likec4.config.json" } -{ "extends": ["../shared/base.json", "../shared/theme.json"] } +``` + +Multiple paths: + +```json +{ "extends": ["../shared/base.json", "../shared/theme.json"] }</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@skills/likec4-dsl/references/configuration.mdaround lines 166 - 170, The
two consecutive JSON objects shown as examples for "extends" are ambiguous;
update the section in configuration.md so each example is clearly labeled and
separated (e.g., "Single path:" with{ "extends": "../shared/likec4.config.json" }and "Multiple paths:" with{ "extends": ["../shared/base.json", "../shared/theme.json"] }), wrap each example in its
own JSON code fence, and add a one-line explanatory note that they are
alternative usages of the extends property to avoid confusion.</details> --- `214-225`: **Consider adding a language identifier to the directory tree block.** The directory structure block triggers a markdown lint warning. Using `text` or leaving it as-is are both acceptable, but adding a language identifier improves consistency. <details> <summary>📝 Suggested fix</summary> ```diff -``` +```text workspace/ ├─ project-a/ │ ├─ likec4.config.json ← project "a"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/likec4-dsl/references/configuration.md` around lines 214 - 225, Update the code block in configuration.md that shows the directory tree to include a language identifier (e.g., change the opening fence from ``` to ```text) so the markdown linter stops warning about an unspecified language; locate the directory structure block under the example workspace (the triple-backtick block containing workspace/, project-a/, project-b/, shared/) and add the language tag to the opening fence.skills/likec4-dsl/references/predicates.md (1)
13-18: Consider adding a language identifier to the grammar code block.The syntax grammar block lacks a language identifier. While BNF/EBNF doesn't have a standard markdown identifier, using
textorbnfimproves consistency and avoids linter warnings.📝 Suggested fix
-``` +```text BASE_PREDICATE ::= WILDCARD | ELEMENT_EXPRESSION | RELATIONSHIP_EXPRESSION FILTER_PREDICATE ::= BASE_PREDICATE where FILTER_CONDITIONS CUSTOM_PREDICATE ::= (BASE_PREDICATE | FILTER_PREDICATE) with { ... } PREDICATE ::= BASE_PREDICATE | FILTER_PREDICATE | CUSTOM_PREDICATE</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@skills/likec4-dsl/references/predicates.mdaround lines 13 - 18, Add a
language identifier to the fenced code block containing the grammar (the block
with BASE_PREDICATE, FILTER_PREDICATE, CUSTOM_PREDICATE, PREDICATE) to satisfy
linters and improve consistency; change the opening fence fromtotext
(or ```bnf) so the grammar lines (BASE_PREDICATE ::= WILDCARD |
ELEMENT_EXPRESSION | RELATIONSHIP_EXPRESSION, FILTER_PREDICATE ::=
BASE_PREDICATE where FILTER_CONDITIONS, CUSTOM_PREDICATE ::= (BASE_PREDICATE |
FILTER_PREDICATE) with { ... }, PREDICATE ::= BASE_PREDICATE | FILTER_PREDICATE
| CUSTOM_PREDICATE) are inside a labeled block.</details> </blockquote></details> <details> <summary>skills/likec4-dsl/references/views.md (1)</summary><blockquote> `84-93`: **Align dynamic-view grammar with the ordering explanation.** The prose explains `exclude` ordering, but `DYNAMIC_VIEW_RULES` only lists `STEP` and style rules. Consider adding `include`/`exclude` entries (or narrowing the prose) to avoid ambiguity. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@skills/likec4-dsl/references/views.md` around lines 84 - 93, The grammar and prose disagree: the DYNAMIC_VIEW_RULES production lists only STEP and DYNAMIC_VIEW_STYLE_RULE but the text discusses include/exclude ordering; update the grammar to reflect the described ordering by adding tokens/productions for include and exclude (e.g., INCLUDE_STEP / EXCLUDE_STEP or explicit INCLUDE_RULE / EXCLUDE_RULE entries) into DYNAMIC_VIEW_RULES so rules are applied in sequence, or alternatively adjust the prose to remove mention of include/exclude and describe only the existing STEP/style semantics; reference DYNAMIC_VIEW_RULES, STEP, and DYNAMIC_VIEW_STYLE_RULE when making the change. ``` </details> </blockquote></details> <details> <summary>packages/language-services/src/common/LikeC4.ts (3)</summary><blockquote> `21-23`: **Consider documenting the magic number for severity.** The value `1` corresponds to `DiagnosticSeverity.Error` from `vscode-languageserver-types`. Since the import was removed, consider adding a brief comment to clarify this mapping for future maintainers. ```diff +// DiagnosticSeverity.Error === 1 (from vscode-languageserver-types) const isErrorDiagnostic = (diagnostic: { severity?: number }): boolean => { return diagnostic.severity === 1 } ``` <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@packages/language-services/src/common/LikeC4.ts` around lines 21 - 23, The function isErrorDiagnostic uses a magic number (1) for diagnostic.severity; document that mapping by adding a brief inline comment near isErrorDiagnostic explaining that 1 corresponds to DiagnosticSeverity.Error (from vscode-languageserver-types) so future maintainers understand the value without the import; keep the function logic unchanged and place the comment next to the isErrorDiagnostic declaration or the diagnostic.severity comparison. ``` </details> --- `204-209`: **Simplify `documentCount()` implementation.** The `toArray()` call creates an intermediate array just to get the length. Consider using a more direct approach if the stream supports it, or document why `toArray()` is necessary. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@packages/language-services/src/common/LikeC4.ts` around lines 204 - 209, documentCount() builds an intermediate array via this.LangiumDocuments.all.toArray().length; replace it with a direct count to avoid allocation: if this.LangiumDocuments.all exposes a size/length property use return this.LangiumDocuments.all.size (or .length), otherwise iterate the iterable and increment a counter (e.g. let c=0; for (const _ of this.LangiumDocuments.all) c++; return c;). Update the documentCount() method accordingly (referencing documentCount and LangiumDocuments.all). ``` </details> --- `165-167`: **Use optional chaining for cleaner code.** As flagged by static analysis, the condition can be simplified using optional chaining. <details> <summary>♻️ Proposed fix</summary> ```diff hasErrors(): boolean { return this.LangiumDocuments.userDocuments.some(doc => { - return doc.diagnostics && doc.diagnostics.some(isErrorDiagnostic) + return doc.diagnostics?.some(isErrorDiagnostic) ?? false }) } ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@packages/language-services/src/common/LikeC4.ts` around lines 165 - 167, Replace the manual null-check with optional chaining: in the expression that inspects this.LangiumDocuments.userDocuments, change the predicate to use doc.diagnostics?.some(isErrorDiagnostic) so the some() call is only invoked when diagnostics exists; reference the LangiumDocuments.userDocuments array and the isErrorDiagnostic function when making this change. ``` </details> </blockquote></details> <details> <summary>packages/likec4/src/cli/validate/index.ts (1)</summary><blockquote> `146-151`: **Stats `filteredFiles` may be misleading when no filter is applied.** When `fileFilter` is null, `filteredFiles` is set to `totalFiles` (all workspace files). However, this doesn't represent files with errors—it represents all files. This could confuse consumers expecting `filteredFiles` to mean "files with errors in scope." Consider renaming or documenting the semantics more clearly, or computing the actual count of files with errors. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@packages/likec4/src/cli/validate/index.ts` around lines 146 - 151, The stats field currently sets filteredFiles to totalFiles when fileFilter is null, which misrepresents "files with errors in scope"; change the logic so stats.filteredFiles always reflects the count of files with errors in scope by using filteredFileSet.size (i.e., set filteredFiles: filteredFileSet.size) instead of conditional totalFiles, and ensure filteredFileSet is constructed to contain only files that have errors (so filteredErrors and filteredFileSet remain consistent); alternatively, if you prefer to keep the existing semantics, rename filteredFiles to something explicit (e.g., scopedFileCount) and update any callers/documentation accordingly. ``` </details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Inline comments:
In@packages/language-services/src/common/LikeC4.ts:
- Around line 172-200: printErrors() currently iterates
this.LangiumDocuments.all causing inconsistency with getErrors()/hasErrors()
which use this.LangiumDocuments.userDocuments; change the iteration in
printErrors() to use this.LangiumDocuments.userDocuments, preserving the
existing filtering (errors = doc.diagnostics?.filter(isErrorDiagnostic) ?? []),
message truncation and logging logic so printed errors match what
getErrors()/hasErrors() report for user documents only.- Around line 148-159: The truncation logic builds a
messagesarray but never
uses it in theerrors.mapcallback, leaving dead code; fix by either removing
themessagesvariable and its truncation block, or by returning the truncated
text (e.g., set the returned object'smessageto the truncated value built
frommessages, e.g., join with '\n'); locate the callback whereerrors.map(({ message, range }) => { ... })and update themessagefield in the returned
object (or remove the unusedmessagesblock) accordingly, keepingrange,
line, andsourceFsPath: doc.uri.fsPathas-is.In
@packages/likec4/src/cli/validate/index.ts:
- Around line 111-116: The fallback for resolving the file path creates entries
like '/workspace/.' when view.sourcePath is undefined; update the resolve call
in the layout error push (layoutErrors.push block) to use a better fallback than
'.' — e.g., use an empty string or view.id (resolve(args.path, view.sourcePath
?? '', ) or resolve(args.path, view.sourcePath ?? view.id)) so reported file
paths are meaningful; ensure you update the message/file pair consistently where
view.sourcePath is referenced.- Around line 134-136: The current file filtering logic (building filteredErrors
from allErrors using fileFilter and e.file.endsWith(f)) can yield false
positives (e.g., "model.c4" matching "other-model.c4"); update the filter in
validate/index.ts to perform a path-aware comparison: for each f in fileFilter
compare against e.file using path utilities (e.g., path.basename(e.file) === f
or normalize both paths and check equality or check endsWith with a path
separator like${path.sep}${f}) so matches respect directory boundaries;
adjust the filtering loop that constructs filteredErrors (references:
filteredErrors, fileFilter, allErrors, e.file) to use the chosen path-based
comparison and ensure both relative and absolute paths are normalized before
comparison.- Around line 119-126: The catch currently lumps all errors into layoutErrors;
change it so infrastructure errors from ensureProjectId are surfaced as
fatal/descriptive errors while only actual layout validation failures are pushed
to layoutErrors. Concretely: in the catch near layoutErrors push, detect
infrastructure errors from ensureProjectId (preferably by making/using a
specific error class like ProjectNotRegisteredError or checking e.name/e.message
for the known ensureProjectId failure texts) and for those call process.exit(1)
or rethrow a clear Error (e.g.,Project ID X is not registered); otherwise
(non-infrastructure errors) keep the existing behavior of pushing a diagnostic
into layoutErrors. Update imports/signatures to use the specific error class if
you add one and reference ensureProjectId, layoutErrors and the current catch
block when making the change.In
@skills/likec4-dsl/references/configuration.md:
- Around line 176-185: The code block contains inline JavaScript-style comments
which are invalid in standard JSON; update the examples around the "landingPage"
object to either remove the comment lines or mark the fences as json5 if
comments are intended. Specifically, provide three separate valid code blocks
showing the "landingPage" examples (one with { "landingPage": { "redirect": true
} }, one with { "landingPage": { "include": ["overview","cloud-detail"] } }, and
one with { "landingPage": { "exclude": ["internal-debug"] } }) and remove the
leading // comments (or change the triple-backtick fence to ```json5 if you want
to keep comments).In
@skills/likec4-dsl/references/deployment.md:
- Around line 171-174: The documentation's style block references an undefined
node "server4" (style server1., server4. { color green }) while the deployment
example only defines server1, server2, and server3; update the example to
include a server4 definition or change the style rule to reference an existing
node (e.g., replace server4._ with server2._ or server3.) so the FQN in the
style rule matches an actual deployment node (look for the deployment model
definitions for server1/server2/server3 and the style block containing
server1., server4._).In
@skills/likec4-dsl/references/dynamic-views.md:
- Line 3: The fenced code block in dynamic-views.md is missing a language tag
which triggers MD040; update the opening triple-backtick fence for the
tree-style block to include the language tag "text" (i.e., change ``` toIn `@skills/likec4-dsl/references/predicates.md`: - Line 26: The example predicate `include * where tag s `#production` // FILTER_PREDICATE` contains a typo; replace `tag s` with `tag is` in the FILTER_PREDICATE example so the predicate reads `tag is `#production`` (fix the example line that includes the comment `// FILTER_PREDICATE`). In `@skills/likec4-dsl/references/views.md`: - Line 14: Several fenced code blocks in the document are missing language identifiers (triggering MD040); update the fences so the block containing the DSL "views { ... }" and the block starting with "include PREDICATE, PREDICATE, ..." use a likec4 fence (```likec4) and the block that defines the grammar "STEP ::=" uses a text fence (```text), ensuring each opening triple-backtick is followed by the correct language identifier to satisfy markdown linting. In `@skills/likec4-dsl/SKILL.md`: - Line 91: Several fenced code blocks in SKILL.md lack language identifiers and fail MD040; update the unlabeled blocks for decision trees to use the language tag "text" and the DSL snippets to use "likec4" (specifically the unlabeled blocks showing the decision tree "What kind of diagram?" and the DSL blocks with "specification { ... }", "model { ... }", and "views { ... }"), i.e., change the opening triple-backtick lines so they read ```text for the decision-tree block and ```likec4 for each DSL snippet (also apply the same change to the other occurrences noted at lines 104, 124, 138, 152, 210, and 369). --- Nitpick comments: In `@packages/language-services/src/common/LikeC4.ts`: - Around line 21-23: The function isErrorDiagnostic uses a magic number (1) for diagnostic.severity; document that mapping by adding a brief inline comment near isErrorDiagnostic explaining that 1 corresponds to DiagnosticSeverity.Error (from vscode-languageserver-types) so future maintainers understand the value without the import; keep the function logic unchanged and place the comment next to the isErrorDiagnostic declaration or the diagnostic.severity comparison. - Around line 204-209: documentCount() builds an intermediate array via this.LangiumDocuments.all.toArray().length; replace it with a direct count to avoid allocation: if this.LangiumDocuments.all exposes a size/length property use return this.LangiumDocuments.all.size (or .length), otherwise iterate the iterable and increment a counter (e.g. let c=0; for (const _ of this.LangiumDocuments.all) c++; return c;). Update the documentCount() method accordingly (referencing documentCount and LangiumDocuments.all). - Around line 165-167: Replace the manual null-check with optional chaining: in the expression that inspects this.LangiumDocuments.userDocuments, change the predicate to use doc.diagnostics?.some(isErrorDiagnostic) so the some() call is only invoked when diagnostics exists; reference the LangiumDocuments.userDocuments array and the isErrorDiagnostic function when making this change. In `@packages/likec4/src/cli/validate/index.ts`: - Around line 146-151: The stats field currently sets filteredFiles to totalFiles when fileFilter is null, which misrepresents "files with errors in scope"; change the logic so stats.filteredFiles always reflects the count of files with errors in scope by using filteredFileSet.size (i.e., set filteredFiles: filteredFileSet.size) instead of conditional totalFiles, and ensure filteredFileSet is constructed to contain only files that have errors (so filteredErrors and filteredFileSet remain consistent); alternatively, if you prefer to keep the existing semantics, rename filteredFiles to something explicit (e.g., scopedFileCount) and update any callers/documentation accordingly. In `@skills/likec4-dsl/references/configuration.md`: - Around line 166-170: The two consecutive JSON objects shown as examples for "extends" are ambiguous; update the section in configuration.md so each example is clearly labeled and separated (e.g., "Single path:" with `{ "extends": "../shared/likec4.config.json" }` and "Multiple paths:" with `{ "extends": ["../shared/base.json", "../shared/theme.json"] }`), wrap each example in its own JSON code fence, and add a one-line explanatory note that they are alternative usages of the extends property to avoid confusion. - Around line 214-225: Update the code block in configuration.md that shows the directory tree to include a language identifier (e.g., change the opening fence from ``` to ```text) so the markdown linter stops warning about an unspecified language; locate the directory structure block under the example workspace (the triple-backtick block containing workspace/, project-a/, project-b/, shared/) and add the language tag to the opening fence. In `@skills/likec4-dsl/references/predicates.md`: - Around line 13-18: Add a language identifier to the fenced code block containing the grammar (the block with BASE_PREDICATE, FILTER_PREDICATE, CUSTOM_PREDICATE, PREDICATE) to satisfy linters and improve consistency; change the opening fence from ``` to ```text (or ```bnf) so the grammar lines (BASE_PREDICATE ::= WILDCARD | ELEMENT_EXPRESSION | RELATIONSHIP_EXPRESSION, FILTER_PREDICATE ::= BASE_PREDICATE where FILTER_CONDITIONS, CUSTOM_PREDICATE ::= (BASE_PREDICATE | FILTER_PREDICATE) with { ... }, PREDICATE ::= BASE_PREDICATE | FILTER_PREDICATE | CUSTOM_PREDICATE) are inside a labeled block. In `@skills/likec4-dsl/references/views.md`: - Around line 84-93: The grammar and prose disagree: the DYNAMIC_VIEW_RULES production lists only STEP and DYNAMIC_VIEW_STYLE_RULE but the text discusses include/exclude ordering; update the grammar to reflect the described ordering by adding tokens/productions for include and exclude (e.g., INCLUDE_STEP / EXCLUDE_STEP or explicit INCLUDE_RULE / EXCLUDE_RULE entries) into DYNAMIC_VIEW_RULES so rules are applied in sequence, or alternatively adjust the prose to remove mention of include/exclude and describe only the existing STEP/style semantics; reference DYNAMIC_VIEW_RULES, STEP, and DYNAMIC_VIEW_STYLE_RULE when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID:
1f9bbcbb-b68d-4b4d-a80f-ff568ff298ac⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml📒 Files selected for processing (17)
.changeset/improve-validate-command.md.claude/skills/likec4-dslapps/docs/astro.config.mjsapps/docs/package.jsonapps/docs/src/content.config.tspackages/language-services/src/common/LikeC4.tspackages/likec4/src/cli/check-update/utils.tspackages/likec4/src/cli/index.tspackages/likec4/src/cli/options.tspackages/likec4/src/cli/validate/index.tspnpm-workspace.yamlskills/likec4-dsl/SKILL.mdskills/likec4-dsl/references/configuration.mdskills/likec4-dsl/references/deployment.mdskills/likec4-dsl/references/dynamic-views.mdskills/likec4-dsl/references/predicates.mdskills/likec4-dsl/references/views.md
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
packages/likec4/src/cli/validate/index.ts (1)
107-126:⚠️ Potential issue | 🔴 CriticalDo not turn invalid
--projectinto a filterable validation diagnostic.
packages/language-services/src/common/LikeC4.ts:95-98resolves the project insidediagrams(). If that throws, this catch wraps the failure as{ file: '' }, so a later--filefilter can drop it and returnvalid: true/ exit0for an invalid project. Re-throw setup/project-resolution failures instead of pushing them intolayoutErrors.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/likec4/src/cli/validate/index.ts` around lines 107 - 126, The catch around languageServices.diagrams(args.project) is turning project-resolution/setup failures into a filterable validation diagnostic; instead, detect and re-throw those setup/project-resolution errors (so they cannot be dropped by a --file filter) and only push true diagram layout validation errors into layoutErrors. Update the try/catch in index.ts: call languageServices.diagrams(args.project) inside try, and in the catch rethrow when the error originates from project resolution (preferably by checking for a specific error type exported by LikeC4 such as ProjectResolutionError or by matching a clear marker on the Error), otherwise push the error into layoutErrors as before; reference symbols: languageServices.diagrams, layoutErrors, args.project, and the project-resolution error type from LikeC4 (e.g., ProjectResolutionError).
🤖 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-services/src/common/LikeC4.ts`:
- Around line 197-201: The documentCount() helper currently returns
this.LangiumDocuments.all.toArray().length which mismatches the validation
helpers getErrors(), hasErrors(), and printErrors() that operate on
LangiumDocuments.userDocuments; change documentCount() to count userDocuments
instead (e.g. use this.LangiumDocuments.userDocuments.toArray().length) so
total/filtered file counts match validation scope, or alternatively add a new
method like documentCountAll() that explicitly returns the .all count and leave
documentCount() aligned with userDocuments; update references to documentCount()
accordingly to preserve semantics.
In `@packages/likec4/src/cli/validate/index.ts`:
- Around line 86-89: The code currently enables automatic model-error printing
via the fromWorkspace printErrors flag (where languageServices is created)
whenever --json is off, and later logs every layoutErrors entry; change behavior
so when a file filter is provided (args.file or equivalent) you disable
automatic printing by setting printErrors to (!isJson && !args.file) when
calling fromWorkspace/creating languageServices, and modify the diagnostics
rendering block that currently iterates layoutErrors to instead iterate and
render filteredErrors (use filteredErrors for both printed output and exit-code
logic) so only scoped diagnostics are printed when --file is used.
- Line 83: The file filter resolution currently uses resolve(f) which resolves
against process.cwd(), causing mismatches with error paths built from the
workspace; update the fileFilter assignment (the args.file => map) to resolve
each entry against the workspace root (args.path) instead of the CWD (i.e., use
resolve(args.path, f) when mapping args.file). This will align fileFilter with
how error paths are constructed (see doc.uri.fsPath and resolve(args.path,
view.sourcePath)) so filters correctly match reported file paths.
In `@skills/likec4-dsl/references/predicates.md`:
- Line 32: The example uses the wrong predicate name: replace the phrase "and
type is component" with "and kind is component" so it matches the predicate
definition (the DSL predicate defined as "kind is ...") and ensures the example
is valid for copy/paste; search for the string "and type is component" in
predicates.md and update it to "and kind is component" (keeping surrounding
whitespace and punctuation consistent).
---
Duplicate comments:
In `@packages/likec4/src/cli/validate/index.ts`:
- Around line 107-126: The catch around languageServices.diagrams(args.project)
is turning project-resolution/setup failures into a filterable validation
diagnostic; instead, detect and re-throw those setup/project-resolution errors
(so they cannot be dropped by a --file filter) and only push true diagram layout
validation errors into layoutErrors. Update the try/catch in index.ts: call
languageServices.diagrams(args.project) inside try, and in the catch rethrow
when the error originates from project resolution (preferably by checking for a
specific error type exported by LikeC4 such as ProjectResolutionError or by
matching a clear marker on the Error), otherwise push the error into
layoutErrors as before; reference symbols: languageServices.diagrams,
layoutErrors, args.project, and the project-resolution error type from LikeC4
(e.g., ProjectResolutionError).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d2dfecf8-6016-419e-9ac1-e55dddad8a50
📒 Files selected for processing (5)
packages/language-services/src/common/LikeC4.tspackages/likec4/src/cli/validate/index.tsskills/likec4-dsl/references/configuration.mdskills/likec4-dsl/references/deployment.mdskills/likec4-dsl/references/predicates.md
✅ Files skipped from review due to trivial changes (1)
- skills/likec4-dsl/references/deployment.md
| await using languageServices = await fromWorkspace(args.path, { | ||
| watch: false, | ||
| printErrors: !isJson, | ||
| throwIfInvalid: false, |
There was a problem hiding this comment.
--file does not scope text-mode diagnostics.
Line 88 still enables automatic model-error printing whenever --json is off, and Lines 163-165 log every layoutErrors entry instead of the filtered subset. So likec4 validate --file ... can still print diagnostics from unrelated files even when filteredErrors and the exit code say the run was scoped. Disable auto-printing when a file filter is present and render from filteredErrors instead.
Also applies to: 162-165
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/likec4/src/cli/validate/index.ts` around lines 86 - 89, The code
currently enables automatic model-error printing via the fromWorkspace
printErrors flag (where languageServices is created) whenever --json is off, and
later logs every layoutErrors entry; change behavior so when a file filter is
provided (args.file or equivalent) you disable automatic printing by setting
printErrors to (!isJson && !args.file) when calling fromWorkspace/creating
languageServices, and modify the diagnostics rendering block that currently
iterates layoutErrors to instead iterate and render filteredErrors (use
filteredErrors for both printed output and exit-code logic) so only scoped
diagnostics are printed when --file is used.
There was a problem hiding this comment.
Intentional — text mode shows all diagnostics during init (useful context), while exit code and summary are scoped to --file. The SKILL uses --json mode which is fully scoped.
There was a problem hiding this comment.
@davydkov, understood — the design is clear: text mode surfaces all diagnostics for context (useful when debugging cascading errors), while --file scoping only affects the exit code and summary. --json mode (the primary interface for the SKILL) is fully scoped. I'll withdraw the concern.
✏️ Learnings added
Learnt from: davydkov
Repo: likec4/likec4 PR: 2782
File: packages/likec4/src/cli/validate/index.ts:86-89
Timestamp: 2026-03-20T09:11:24.853Z
Learning: In `packages/likec4/src/cli/validate/index.ts`, text mode intentionally prints ALL diagnostics (model errors via `printErrors` during init, and all layout errors) regardless of the `--file` filter. The `--file` filter only scopes the exit code and the final summary line. The `--json` mode is the fully-scoped output path and is the primary interface consumed by the LikeC4 DSL SKILL. This asymmetry is by design, not a bug.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: CR
Repo: likec4/likec4 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-21T16:24:15.549Z
Learning: Applies to **/*.agent.{ts,tsx,js,jsx} : Agents must validate input before processing and provide meaningful error messages
Learnt from: CR
Repo: likec4/likec4 PR: 0
File: packages/core/AGENTS.md:0-0
Timestamp: 2026-02-11T10:07:53.330Z
Learning: Applies to packages/core/src/manual-layout/**/*.{ts,tsx,js,jsx} : When changes relate to views (types or models), update View-drifts detection/auto-applying in `src/manual-layout` accordingly. If unsure what leads to layout drifts or can be auto-applied, ask for confirmation.
Learnt from: davydkov
Repo: likec4/likec4 PR: 2782
File: skills/likec4-dsl/references/dynamic-views.md:3-3
Timestamp: 2026-03-20T08:57:15.663Z
Learning: Files under the `skills/` directory in the `likec4/likec4` repository (e.g., `skills/likec4-dsl/references/`) are LLM skill reference files, not published documentation. Markdown linting rules (such as MD040 for fenced code block language tags) should not be applied to these files during code review.
There was a problem hiding this comment.
🧹 Nitpick comments (2)
packages/language-services/src/common/LikeC4.ts (2)
158-160: Consider using optional chaining for conciseness.The static analyzer flagged that optional chaining would be more idiomatic here.
♻️ Proposed fix
hasErrors(): boolean { return this.LangiumDocuments.userDocuments.some(doc => { - return doc.diagnostics && doc.diagnostics.some(isErrorDiagnostic) + return doc.diagnostics?.some(isErrorDiagnostic) ?? false }) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/language-services/src/common/LikeC4.ts` around lines 158 - 160, Replace the verbose null-check in the predicate with optional chaining: inside the some over this.LangiumDocuments.userDocuments (the arrow function that currently checks doc.diagnostics && doc.diagnostics.some(isErrorDiagnostic)), use doc.diagnostics?.some(isErrorDiagnostic) (or Boolean(doc.diagnostics?.some(isErrorDiagnostic))) so the code is more concise and idiomatic while still using the existing LangiumDocuments, userDocuments and isErrorDiagnostic symbols.
197-202: Consider using.toArray().lengthfor consistency and explicitness.The
userDocumentsproperty returns aStream<LikeC4LangiumDocument>which doesn't expose a direct.lengthor.sizeproperty. While spreading to get the length works, it's slightly inefficient since it forces full array materialization. Other parts of the codebase explicitly call.toArray()(e.g.,packages/language-services/src/node/index.ts) before accessing.length. For consistency and clarity, use.toArray().lengthinstead of spreading.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/language-services/src/common/LikeC4.ts` around lines 197 - 202, The documentCount() method currently computes length by spreading LangiumDocuments.userDocuments into an array; change it to call LangiumDocuments.userDocuments.toArray().length for consistency and explicit materialization (replace [...this.LangiumDocuments.userDocuments].length with this.LangiumDocuments.userDocuments.toArray().length in the documentCount() method).
🤖 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-services/src/common/LikeC4.ts`:
- Around line 158-160: Replace the verbose null-check in the predicate with
optional chaining: inside the some over this.LangiumDocuments.userDocuments (the
arrow function that currently checks doc.diagnostics &&
doc.diagnostics.some(isErrorDiagnostic)), use
doc.diagnostics?.some(isErrorDiagnostic) (or
Boolean(doc.diagnostics?.some(isErrorDiagnostic))) so the code is more concise
and idiomatic while still using the existing LangiumDocuments, userDocuments and
isErrorDiagnostic symbols.
- Around line 197-202: The documentCount() method currently computes length by
spreading LangiumDocuments.userDocuments into an array; change it to call
LangiumDocuments.userDocuments.toArray().length for consistency and explicit
materialization (replace [...this.LangiumDocuments.userDocuments].length with
this.LangiumDocuments.userDocuments.toArray().length in the documentCount()
method).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 44caf9e6-ef6b-49d6-8281-ff16a917d88e
📒 Files selected for processing (2)
packages/language-services/src/common/LikeC4.tsskills/likec4-dsl/references/predicates.md
- Fix exit code bug (was never set on validation failure) - Add --json flag for structured JSON output (for tooling/SKILL consumers) - Add --file flag to scope errors to specific files (handles cascading errors) - Add --no-layout flag to skip layout drift checks - Add success/failure summary messages and timing - Add --project support for multi-project workspaces - Add documentCount() to LikeC4 language-services class - Add LikeC4 DSL skill with references for configuration, views, predicates, deployment, dynamic views Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Remove dead code: unused message truncation in getErrors() - Fix printErrors() to iterate userDocuments (consistent with getErrors/hasErrors) - Fix layout drift file path fallback (avoid '/workspace/.') - Fix file filter endsWith false positives (require path separator) - Fix typo 'tag s' → 'tag is' in predicates.md - Fix undefined server4 → server2 in deployment.md example - Fix invalid JSON comments in configuration.md landingPage section Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Fix documentCount() to use userDocuments (consistent with getErrors/hasErrors/printErrors) - Fix typo 'type is component' → 'kind is component' in predicates.md Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The symlink was pointing to ./skills/likec4-dsl/ which resolved relative to .claude/skills/ directory (wrong path). Fixed to ../../skills/likec4-dsl to correctly traverse up to repo root. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Address remaining review comments from CodeRabbit by adding language identifiers to all unlabeled fenced code blocks. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Document serve, build, export, codegen, mcp, and format commands with key options and examples. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Move CLI docs from SKILL.md inline to references/cli.md so it's only loaded when needed, reducing the default skill context size. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Compact, token-optimized examples covering: extend elements/relations, view inheritance, groups, global styles/predicates, dynamic views with parallel/notes/navigateTo, deployment with instanceOf, rank, where predicates, relationship kinds, and a complete mini-project. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
9f403bb to
b97e08f
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
skills/likec4-dsl/SKILL.md (1)
48-66:⚠️ Potential issue | 🟡 Minor
jsonexample is invalid due to inline comments.The
statsobject uses//comments inside a```jsonblock, so the example is not valid JSON and can fail copy/paste validation.🛠️ Proposed fix
"stats": { - "totalFiles": 100, // Total number of files in the project - "totalErrors": 500, // Total number of errors in the project - "filteredFiles": 1, // Number of files that match the --file filter - "filteredErrors": 1 // Number of errors in the filtered files + "totalFiles": 100, + "totalErrors": 500, + "filteredFiles": 1, + "filteredErrors": 1 }#!/bin/bash # Read-only check: find JSON-fenced blocks in SKILL.md that contain JS-style comments. # Expected: no matches after fix. awk ' /^```json$/ { in_json=1; next } /^```$/ && in_json { in_json=0; next } in_json && /\/\// { print FNR ":" $0 } ' skills/likec4-dsl/SKILL.md🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/likec4-dsl/SKILL.md` around lines 48 - 66, The JSON example in the ```json``` block contains JS-style inline comments inside the stats object which makes it invalid JSON; edit the SKILL.md JSON example to remove the // comments (or replace them with real numeric values or a separate explanatory field) so the block is valid JSON, specifically update the "stats" object in the code fence (the keys "totalFiles", "totalErrors", "filteredFiles", "filteredErrors") to not include any // comments and ensure the entire fenced block parses as strict JSON.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@skills/likec4-dsl/references/predicates.md`:
- Around line 9-10: Remove the stray trailing apostrophe from the bullet text
"Custom predicates - used to override properties of elements/relationships (can
be used with `include` only)'" so it reads without the extra quote; update the
string in the predicates.md entry that contains "Custom predicates - used to
override properties of elements/relationships (can be used with `include`
only)'" to remove the final single quote character.
---
Duplicate comments:
In `@skills/likec4-dsl/SKILL.md`:
- Around line 48-66: The JSON example in the ```json``` block contains JS-style
inline comments inside the stats object which makes it invalid JSON; edit the
SKILL.md JSON example to remove the // comments (or replace them with real
numeric values or a separate explanatory field) so the block is valid JSON,
specifically update the "stats" object in the code fence (the keys "totalFiles",
"totalErrors", "filteredFiles", "filteredErrors") to not include any // comments
and ensure the entire fenced block parses as strict JSON.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3dad925e-9997-4e3d-ac8e-83914b0673e6
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (14)
.changeset/ai-coding-agent-skill.md.claude/skills/likec4-dslapps/docs/astro.config.mjsapps/docs/package.jsonapps/docs/src/content.config.tspackages/language-services/src/common/LikeC4.tspackages/likec4/src/cli/check-update/utils.tspnpm-workspace.yamlskills/likec4-dsl/SKILL.mdskills/likec4-dsl/references/cli.mdskills/likec4-dsl/references/configuration.mdskills/likec4-dsl/references/examples.mdskills/likec4-dsl/references/predicates.mdskills/likec4-dsl/references/views.md
✅ Files skipped from review due to trivial changes (6)
- .claude/skills/likec4-dsl
- pnpm-workspace.yaml
- .changeset/ai-coding-agent-skill.md
- apps/docs/package.json
- skills/likec4-dsl/references/cli.md
- skills/likec4-dsl/references/examples.md
🚧 Files skipped from review as they are similar to previous changes (4)
- apps/docs/astro.config.mjs
- apps/docs/src/content.config.ts
- packages/likec4/src/cli/check-update/utils.ts
- skills/likec4-dsl/references/views.md
| - Custom predicates - used to override properties of elements/relationships (can be used with `include` only)' | ||
|
|
There was a problem hiding this comment.
Remove trailing apostrophe in custom-predicate bullet.
There is an extra ' after “include only)” that reads like a typo in the reference text.
✏️ Proposed fix
-- Custom predicates - used to override properties of elements/relationships (can be used with `include` only)'
+- Custom predicates - used to override properties of elements/relationships (can be used with `include` only)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/likec4-dsl/references/predicates.md` around lines 9 - 10, Remove the
stray trailing apostrophe from the bullet text "Custom predicates - used to
override properties of elements/relationships (can be used with `include`
only)'" so it reads without the extra quote; update the string in the
predicates.md entry that contains "Custom predicates - used to override
properties of elements/relationships (can be used with `include` only)'" to
remove the final single quote character.
Explain Agent Skills Discovery RFC, installation via `npx skills add https://likec4.dev/`, and skill structure. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Rename tooling/mcp.mdx → tooling/ai-tools.mdx - Add Agent Skills section on top with install command - Demote MCP content under ## MCP Server heading - Add /tooling/mcp/ → /tooling/ai-tools/ redirect - Update editors.mdx link Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Summary
astro-skillspluginCLI improvements split into #2790.
Test plan
astro-skillsplugin🤖 Generated with Claude Code