bc-atlas 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bca.example.json +11 -0
- package/CHANGELOG.md +190 -0
- package/README.md +18 -9
- package/package.json +5 -3
- package/schemas/bca.schema.json +214 -0
- package/src/al/compiler.js +64 -14
- package/src/al/index.js +2 -1
- package/src/al/settings.js +53 -9
- package/src/analyzer.js +14 -1
- package/src/app/service.js +24 -3
- package/src/app/snapshot.js +8 -4
- package/src/app/ui/app.css +13 -0
- package/src/app/ui/app.js +203 -14
- package/src/app/workspace.js +86 -7
- package/src/architecture.js +13 -2
- package/src/automation/config.js +4 -1
- package/src/automation/pipelines.js +21 -4
- package/src/automation/run.js +12 -3
- package/src/blueprint/cluster.js +52 -16
- package/src/blueprint/components.js +34 -10
- package/src/blueprint/explain.js +111 -0
- package/src/blueprint/index.js +9 -5
- package/src/blueprint/propose.js +118 -19
- package/src/blueprint/report.js +37 -1
- package/src/blueprint/settings.js +147 -0
- package/src/capabilities.js +59 -4
- package/src/cli/handlers.js +49 -0
- package/src/cli/help.js +1 -0
- package/src/cli.js +8 -30
- package/src/codegraph.js +85 -15
- package/src/commands/blueprint.js +13 -0
- package/src/commands/export.js +10 -2
- package/src/commands/graph.js +13 -0
- package/src/commands/report.js +19 -2
- package/src/diagram/layout-cache.js +113 -0
- package/src/diagram/layout.js +7 -3
- package/src/graph/document.js +16 -6
- package/src/graph/platform.js +217 -0
- package/src/handbook-text.js +185 -0
- package/src/handbook.js +416 -0
- package/src/health.js +5 -1
- package/src/insights.js +3 -1
- package/src/knowledge/graph.js +20 -3
- package/src/knowledge/vocabulary.js +6 -0
- package/src/mcp.js +53 -1
- package/src/metadata.js +200 -0
- package/src/parse-cache.js +1 -1
- package/src/quality-rules.js +135 -0
- package/src/resolver.js +16 -4
- package/src/symbols.js +154 -18
- package/vendor/graph-viewer.js +599 -587
package/.bca.example.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "./node_modules/bc-atlas/schemas/bca.schema.json",
|
|
2
3
|
"view": "project",
|
|
3
4
|
"projectRoot": ".",
|
|
4
5
|
"direction": "right",
|
|
@@ -71,6 +72,16 @@
|
|
|
71
72
|
"strictLayers": false,
|
|
72
73
|
"maxObjects": 1500,
|
|
73
74
|
"couplingWeights": { "reads": 2, "subscribes": 1 },
|
|
75
|
+
"proposal": {
|
|
76
|
+
"groupBy": "auto",
|
|
77
|
+
"startFrom": ["namespace", "folder"],
|
|
78
|
+
"ignore": ["permits", "includes"],
|
|
79
|
+
"granularity": 1,
|
|
80
|
+
"sharedCore": true,
|
|
81
|
+
"keep": [{ "name": "Core", "match": ["namespace:Contoso.Core"], "description": "Defined by the team" }],
|
|
82
|
+
"exclude": ["type:permissionset", "folder:test"],
|
|
83
|
+
"moves": { "minGain": 2, "limit": 50 }
|
|
84
|
+
},
|
|
74
85
|
"severity": "error",
|
|
75
86
|
"unassigned": "warning",
|
|
76
87
|
"severities": {
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,196 @@ All notable changes to BC Atlas will be documented here. The format is based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
|
|
5
5
|
follows [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## 0.16.0 - 2026-11-06
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- You decide what the architecture proposal takes into account and how it
|
|
12
|
+
builds components: `architecture.proposal` in `.bca.json` sets the grouping,
|
|
13
|
+
the structures it starts from (`startFrom`), relation kinds that never shape
|
|
14
|
+
components (`ignore`), how finely it splits (`granularity`,
|
|
15
|
+
`appGranularity`), whether a shared core forms (`sharedCore`), components
|
|
16
|
+
you define yourself (`keep`), objects that should not shape components
|
|
17
|
+
(`exclude`), and which moves it lists (`moves`). `bca architecture
|
|
18
|
+
--propose` has `--start-from`, `--ignore`, `--granularity`, and
|
|
19
|
+
`--shared-core`, and the MCP tool and the app take the same settings.
|
|
20
|
+
- Every proposal says how it was made (`proposal.basis` in JSON, **How this
|
|
21
|
+
proposal was made** in the reports, **What was considered** in the app):
|
|
22
|
+
which objects and relation kinds shaped it, their weights, the settings, and
|
|
23
|
+
whether each value came from `.bca.json` or an option.
|
|
24
|
+
- `schemas/bca.schema.json` describes `.bca.json`; the VS Code extension
|
|
25
|
+
applies it, so `.bca.json` gets completion and checks.
|
|
26
|
+
- The system handbook (`bca export --view handbook`, the `handbook` task of
|
|
27
|
+
`bca run` and the GitHub Action) explains an app across all its objects, on
|
|
28
|
+
pages generated from the source:
|
|
29
|
+
- what it consists of: apps, components, object types, central objects
|
|
30
|
+
- its events, with publishers and subscribers
|
|
31
|
+
- its data: who inserts, modifies, deletes, and reads each table
|
|
32
|
+
- its permission sets, and the tables none of them covers
|
|
33
|
+
- its interfaces, with implementations and enum bindings
|
|
34
|
+
- what users can open, by usage category, and its APIs
|
|
35
|
+
- its code health: complexity, size, obsolete code, documentation coverage
|
|
36
|
+
|
|
37
|
+
See `docs/handbook.md` and `examples/handbook`.
|
|
38
|
+
- The handbook links object names to their pages in the object catalog: use
|
|
39
|
+
`--catalog <folder>`, or `handbook.catalog` in `.bca.json`. `bca run` links
|
|
40
|
+
them on its own when the same run writes the catalog.
|
|
41
|
+
- The app and the VS Code panel have a **Handbook** page. Object names there
|
|
42
|
+
open their object page.
|
|
43
|
+
- Objects from symbol packages (`.app`) carry metadata too: caption, access,
|
|
44
|
+
obsolete state, data classification, kind, and size, read from
|
|
45
|
+
`SymbolReference.json`. Objects that newer symbol files nest under
|
|
46
|
+
`Namespaces` are read as well.
|
|
47
|
+
- The handbook in German: `--language de` (`handbook.language`). The terms
|
|
48
|
+
follow the German Business Central client, and the app and the VS Code
|
|
49
|
+
panel switch between English and German.
|
|
50
|
+
- `bca export --view report --handbook` (`report.handbook`) adds the handbook
|
|
51
|
+
to the report, linked to the catalog with `--codegraph`. The new MCP tool
|
|
52
|
+
`bc_atlas_handbook` lets agents read it.
|
|
53
|
+
- `bca architecture --explain <object>` and **Why in …** on the app's object
|
|
54
|
+
page explain where an object belongs: the selector that assigns it and its
|
|
55
|
+
coupling to each component.
|
|
56
|
+
- The app edits what the proposal considers. **Keep component** and
|
|
57
|
+
**Release component** change `architecture.proposal.keep`; **Exclude from
|
|
58
|
+
shaping** and **Shape components again** change `architecture.proposal.exclude`.
|
|
59
|
+
- `bca check` has quality rules that read the objects' metadata:
|
|
60
|
+
- `missing-data-classification` and `obsolete-without-tag` (warning)
|
|
61
|
+
- `high-complexity` above `check.maxComplexity`, default 25 (warning)
|
|
62
|
+
- `missing-tooltip`, `obsolete-without-reason`, and
|
|
63
|
+
`undocumented-public-api` (info)
|
|
64
|
+
|
|
65
|
+
Each rule reports once per object, and `check.severities` sets it to
|
|
66
|
+
error, warning, info, or off. On Microsoft's System Application they find 17
|
|
67
|
+
public codeunits with undocumented procedures and 5 codeunits with
|
|
68
|
+
procedures above complexity 25, and no false positives in the samples
|
|
69
|
+
checked against the source.
|
|
70
|
+
- Event subscriber relations record the event they subscribe to (`event` on
|
|
71
|
+
`subscribes` edges).
|
|
72
|
+
- Objects, fields, and procedures carry `metadata` that describes what they
|
|
73
|
+
are. The values are normalized from the AL source:
|
|
74
|
+
- from `///` documentation comments: the summary text
|
|
75
|
+
- from properties: caption and translator comment, access, extensible,
|
|
76
|
+
obsolete state, reason, and tag, and data classification
|
|
77
|
+
- the object's kind: page, table, and query type, subtype, source table,
|
|
78
|
+
`TableNo`, usage category, application area, and API
|
|
79
|
+
- permissions and inherent permissions
|
|
80
|
+
- size: lines, fields, keys, procedures, triggers, events, actions
|
|
81
|
+
- cyclomatic complexity per procedure, plus total and maximum per object
|
|
82
|
+
|
|
83
|
+
The object catalog has an **Overview** section, and its procedure tables add
|
|
84
|
+
lines, complexity, and descriptions. Tables and pages list their procedures
|
|
85
|
+
and triggers too. The app's object page has an **About** card. The knowledge
|
|
86
|
+
graph exports documentation, obsolete state, data classification, page type,
|
|
87
|
+
line count, and complexity.
|
|
88
|
+
|
|
89
|
+
### Fixed
|
|
90
|
+
|
|
91
|
+
Found by running BC Atlas on Microsoft's System Application source (1,345
|
|
92
|
+
files) and on the real Base Application 29 symbols:
|
|
93
|
+
|
|
94
|
+
- Symbol packages:
|
|
95
|
+
- objects nested under `Namespaces` are read (with #85); before, almost
|
|
96
|
+
every object of the Base Application was missing
|
|
97
|
+
- enums (`EnumTypes`, `EnumExtensionTypes`), profiles, profile extensions,
|
|
98
|
+
and control add-ins load too
|
|
99
|
+
- page field counts read the numeric control kinds, action counts include
|
|
100
|
+
the actions inside groups, and local methods count as local
|
|
101
|
+
- a page's source table is named instead of given by ID, and application
|
|
102
|
+
areas lose their `#`
|
|
103
|
+
- An object that refers to itself (a variable of its own type) is no longer
|
|
104
|
+
reported as a dependency cycle.
|
|
105
|
+
- The architecture proposal keeps an app or module whose objects have no
|
|
106
|
+
relations to each other (a module of only permission sets or control
|
|
107
|
+
add-ins) as one component named after it, not "Unconnected". Permission
|
|
108
|
+
sets the relations leave unconnected join the component, within their own
|
|
109
|
+
app or module, that holds most of the objects they grant.
|
|
110
|
+
- The handbook's documentation coverage counts only public procedures of
|
|
111
|
+
public objects (the API other apps can call); on the System Application,
|
|
112
|
+
96% instead of a misleading 47%.
|
|
113
|
+
- The handbook with `--catalog` analyzes the project once instead of twice.
|
|
114
|
+
- `///` summaries are found above `#pragma` and other preprocessor lines,
|
|
115
|
+
as the System Application writes them.
|
|
116
|
+
|
|
117
|
+
- Knowledge graph captions no longer include `Comment = ...` and other options
|
|
118
|
+
of the Caption property. `bca:access` now comes from the `Access` property of
|
|
119
|
+
every object, not only permission sets.
|
|
120
|
+
- The object catalog's global-variable table no longer has a Properties column
|
|
121
|
+
that was always empty.
|
|
122
|
+
- The AL compiler no longer fails with AL1018 ("Directory could not be
|
|
123
|
+
found") on every run: assembly probing folders that do not exist, such as
|
|
124
|
+
the AL default `./.netpackages` that VS Code reports even when it is
|
|
125
|
+
absent, are left out of the call, as package cache folders already were.
|
|
126
|
+
- VS Code: symbols that the AL Language extension resolves are found by BC
|
|
127
|
+
Atlas too. The extension passed the AL defaults (`./.alpackages`,
|
|
128
|
+
`./.netpackages`) of settings nobody set, and these overrode every
|
|
129
|
+
project's own `.vscode/settings.json` and the `.code-workspace` settings,
|
|
130
|
+
so a `al.packageCachePath` such as `../symbols` was ignored and the
|
|
131
|
+
compiler and the symbol loader reported missing packages. Now only values
|
|
132
|
+
someone set are passed, by layer (user, workspace, workspace folder), and a
|
|
133
|
+
project's own settings win, as in VS Code.
|
|
134
|
+
- The explorer timeline loads symbols from the configured `al.packageCachePath`
|
|
135
|
+
too, not only from `.alpackages`.
|
|
136
|
+
- A rule set or analyzer that does not exist no longer stops the compile:
|
|
137
|
+
it is left out and reported as `al-ruleset-missing` or
|
|
138
|
+
`al-analyzer-missing` next to `app.json`. A toolchain without an analyzer
|
|
139
|
+
folder skips code analysis instead of failing the whole run.
|
|
140
|
+
- `al.*` path settings expand `${workspaceFolder}`, `${userHome}`,
|
|
141
|
+
`${env:NAME}`, and `~`, as VS Code does; before, such a path pointed nowhere.
|
|
142
|
+
In VS Code, `${workspaceFolder}` is the editor's workspace folder.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- The BC Atlas GitHub Action (new `cache` input, on by default) and the
|
|
147
|
+
workflows and pipelines that `bca setup` writes keep the BC Atlas cache
|
|
148
|
+
folder between runs (`actions/cache`, Azure `Cache@2`), so CI benefits from
|
|
149
|
+
the parse and layout caches too. Generated GitHub workflows use
|
|
150
|
+
`actions/checkout@v7`, `actions/setup-node@v7`, `actions/cache@v6`, and
|
|
151
|
+
`actions/upload-artifact@v7`.
|
|
152
|
+
- Dependabot also updates the VS Code extension's dependencies.
|
|
153
|
+
- Repeated `bca check`, `bca export`, and `bca run` calls are several times
|
|
154
|
+
faster with identical output: diagram layouts are cached by their exact
|
|
155
|
+
content, the CLI reuses the parse results of unchanged files (as VS Code
|
|
156
|
+
already did), and views no longer deep-copy the analyzed model. On a
|
|
157
|
+
synthetic 390-file app, a warm `bca export --view report` takes 0.5 instead
|
|
158
|
+
of 5.1 s, a project diagram 0.4 instead of 3.7 s, and `bca check` 0.4
|
|
159
|
+
instead of 1.2 s. `BCA_LAYOUT_CACHE=off` and `BCA_PARSE_CACHE=off` turn the
|
|
160
|
+
caches off.
|
|
161
|
+
- `scripts/benchmark.js` (`npm run benchmark`) generates a synthetic app and
|
|
162
|
+
times commands cold and warm.
|
|
163
|
+
- `bca --version`, help, and usage errors start in about 50 instead of 280 ms:
|
|
164
|
+
command modules load only when their command runs.
|
|
165
|
+
- Faster 3D explorer and architecture proposal; on a 2,800-object app with a
|
|
166
|
+
Base-Application-sized symbol package, the explorer opens in 0.4 instead of
|
|
167
|
+
2.3 s and a proposal takes 0.4 instead of 1.3 s, with identical results:
|
|
168
|
+
- symbol packages are unzipped and parsed once per file version instead of
|
|
169
|
+
for every page;
|
|
170
|
+
- the explorer and the architecture pages reuse the app's analyzed model
|
|
171
|
+
instead of analyzing or copying it again;
|
|
172
|
+
- `object:` selectors are looked up by name: a proposal has one per
|
|
173
|
+
misplaced object, and each was tested against every object of the model;
|
|
174
|
+
- AL names are normalized once.
|
|
175
|
+
- A failed compile without any symbol package reports one
|
|
176
|
+
`al-symbols-missing` hint ("Run AL: Download Symbols") next to `app.json`.
|
|
177
|
+
|
|
178
|
+
## 0.15.0 - 2026-11-05
|
|
179
|
+
|
|
180
|
+
### Added
|
|
181
|
+
|
|
182
|
+
- Saved graphs are a reusable platform: analyze once, query repeatedly, and
|
|
183
|
+
render for a specific use case without re-analyzing AL.
|
|
184
|
+
- `bca graph query` and the MCP tool `bc_atlas_graph_query` select roots,
|
|
185
|
+
named root groups, traversal depth, dependency or caller direction,
|
|
186
|
+
relation kinds, graph levels, and temporal presence frames. Native Atlas
|
|
187
|
+
graphs and version 1 nodes/edges snapshots retain their original IDs,
|
|
188
|
+
evidence, unresolved boundaries, and metadata in reusable JSON slices.
|
|
189
|
+
- `bca graph render` and `bc_atlas_graph_render` write SVG, self-contained
|
|
190
|
+
static HTML, Graphviz DOT, or JSON. SVG and HTML use the existing local
|
|
191
|
+
renderer without requiring Graphviz; roots are highlighted and every
|
|
192
|
+
selected node and edge is retained.
|
|
193
|
+
- Graph validation rejects unsupported versions, invalid roots, and missing
|
|
194
|
+
endpoints, prevents overwriting the input, and rejects oversized visual
|
|
195
|
+
selections explicitly rather than truncating dependencies.
|
|
196
|
+
|
|
7
197
|
## 0.14.0 - 2026-11-05
|
|
8
198
|
|
|
9
199
|
### Added
|
package/README.md
CHANGED
|
@@ -15,7 +15,8 @@ BC Atlas (`bca`) parses AL with
|
|
|
15
15
|
objects, calls, events, data access, and permissions into an architecture
|
|
16
16
|
model, and shows it in one app: overview, health, a target architecture with
|
|
17
17
|
the work to reach it, a 3D dependency explorer, diagrams, one page per object,
|
|
18
|
-
and documentation from UI tests. The same results are
|
|
18
|
+
a system handbook, and documentation from UI tests. The same results are
|
|
19
|
+
files for Git and CI.
|
|
19
20
|
Parser and renderer are WebAssembly: Node.js is the only requirement.
|
|
20
21
|
|
|
21
22
|
**Documentation: [schulzoli.github.io/BC-Atlas](https://schulzoli.github.io/BC-Atlas/)**
|
|
@@ -26,6 +27,7 @@ cd path/to/al-project
|
|
|
26
27
|
bca setup # .bca.json, Husky hooks, VS Code tasks, pipeline, schedule (or: bca setup agent)
|
|
27
28
|
bca check # architecture gate for CI
|
|
28
29
|
bca export --view report # docs/atlas/README.md: overview, diagrams, health
|
|
30
|
+
bca export --view handbook # docs/handbook: events, data, permissions, UI, code health
|
|
29
31
|
bca update # new version? see what changed and update everything in one step
|
|
30
32
|
```
|
|
31
33
|
|
|
@@ -37,14 +39,17 @@ In VS Code, install the **BC Atlas** extension and open an AL project:
|
|
|
37
39
|
|
|
38
40
|
| Area | Command | What you get |
|
|
39
41
|
| --- | --- | --- |
|
|
40
|
-
| **In VS Code** | BC Atlas extension | Everything below in the editor: a panel with overview, health, architecture, 3D dependencies, diagrams, objects, and docs; findings in the Problems panel; CodeLens above AL objects; the MCP server for agents. [Guide](./docs/vscode.md) |
|
|
42
|
+
| **In VS Code** | BC Atlas extension | Everything below in the editor: a panel with overview, health, architecture, 3D dependencies, diagrams, objects, the handbook, and docs; findings in the Problems panel; CodeLens above AL objects; the MCP server for agents. [Guide](./docs/vscode.md) |
|
|
41
43
|
| **Get started** | `bca setup` | Guided setup in the terminal or through your AI agent (Claude Code, Copilot, Cursor): a starter `.bca.json`, features, Husky or Git hooks, GitHub Actions or Azure Pipelines, cron schedule, and sync. |
|
|
42
|
-
| **Analyze** | `bca check` | Health findings - cycles, forbidden dependencies, architecture violations, hot spots, diagnostics, and AL compiler and CodeCop/UICop/AppSourceCop findings - with a CI exit code, also as SARIF for code scanning. |
|
|
43
|
-
| | `bca architecture` | Find a target architecture (components, layers), list every dependency that blocks it with how to resolve it, and enforce it with a shrinking baseline. [Guide](./docs/clean-architecture.md) |
|
|
44
|
+
| **Analyze** | `bca check` | Health findings - cycles, forbidden dependencies, architecture violations, hot spots, missing DataClassification or ToolTips, obsolete markings without a tag, complex procedures, undocumented public API, diagnostics, and AL compiler and CodeCop/UICop/AppSourceCop findings - with a CI exit code, also as SARIF for code scanning. [Rules](./docs/health-checks.md) |
|
|
45
|
+
| | `bca architecture` | Find a target architecture (components, layers), list every dependency that blocks it with how to resolve it, and enforce it with a shrinking baseline. You decide what the proposal considers (`architecture.proposal`: relation kinds, starting structures, granularity, components you keep, objects you exclude), it says how it was made, and `--explain` says why an object is where it is. [Guide](./docs/clean-architecture.md) |
|
|
46
|
+
| | `bca graph query` | Reuse a saved graph for impact analysis or message migrations without re-analyzing AL; keep IDs, directions, evidence, and metadata. [Guide](./docs/dependency-explorer.md#query-and-render-saved-graphs) |
|
|
44
47
|
| **Export** | `bca export` | Everything the extension shows, as files: the BC Atlas pages as one offline HTML file to share (default), the Markdown report ([example](./examples/report/README.md)), the 3D explorer, one Markdown page per object, any of ten diagram views as D2, SVG, PNG, PDF, or JSON, with `--watch`, and the project as a knowledge graph in RDF with an OWL ontology ([Turtle, RDF/XML, OWL, N-Triples, JSON-LD](./docs/knowledge-graph.md)). |
|
|
48
|
+
| | `bca export --view handbook` | The system handbook: what the app consists of, its events, data (who inserts, modifies, deletes, reads each table), permissions, interfaces, user interface, and code health, across all objects, in English or German, linked to the object catalog. [Guide](./docs/handbook.md), [example](./examples/handbook/README.md) |
|
|
45
49
|
| | `bca docs` | User guides and test cases from AL UI tests (`[SCENARIO]`, `[GIVEN]`, `[WHEN]`, `[THEN]`) as Markdown, HTML, DITA 1.3, or Azure DevOps CSV, with real captions and translations, a flow diagram per scenario, and BPMN 2.0 processes per use case. [Example](./examples/docs/index.md) |
|
|
50
|
+
| | `bca graph render` | Render saved graph selections as SVG, static HTML, DOT, or JSON through the CLI or MCP, locally and without Graphviz. |
|
|
46
51
|
| **Integrate** | `bca run` | One entry point for Git hooks, schedules, and pipelines; verifies, stages, or publishes generated files. Also available as a [GitHub Action](./docs/automation-and-ci.md#github-actions). |
|
|
47
|
-
| | `bca update` | "BC Atlas 0.
|
|
52
|
+
| | `bca update` | "BC Atlas 0.16.0 is available": release notes, one-step update, and regenerated hooks, tasks, and pipelines. Dependabot pull requests on request. |
|
|
48
53
|
| | `bca mcp` | A Model Context Protocol server for AI agents; `bca help --format json` is the versioned command contract. |
|
|
49
54
|
|
|
50
55
|
Run `bca` for the same overview in your terminal and `bca help <command>` for
|
|
@@ -123,6 +128,10 @@ Generated from the checked-in [warehouse example](./examples/README.md).
|
|
|
123
128
|
- permission sets: table-data `RIMD` rights, execute rights, and composed sets
|
|
124
129
|
across dependent apps;
|
|
125
130
|
- pages, parts, actions, and navigation;
|
|
131
|
+
- what characterizes each object, field, and procedure: captions, `///`
|
|
132
|
+
summaries, access, obsolete state, data classification, page and table
|
|
133
|
+
types, size, and cyclomatic complexity, also for objects in symbol
|
|
134
|
+
packages;
|
|
126
135
|
- `app.json` metadata, `.alpackages` symbols and `al.packageCachePath`,
|
|
127
136
|
`.code-workspace` multi-root workspaces, cycles, hubs, orphans, and
|
|
128
137
|
unresolved references.
|
|
@@ -180,10 +189,10 @@ search, or browse them here, starting with the [table of contents](./docs/_TOC_.
|
|
|
180
189
|
- [Architecture reports](./docs/reports.md) and [health checks](./docs/health-checks.md)
|
|
181
190
|
- [Architecture diagrams and views](./docs/architecture-diagrams.md)
|
|
182
191
|
- [Configuration](./docs/configuration.md) and the complete [`.bca.example.json`](./.bca.example.json)
|
|
183
|
-
- [
|
|
192
|
+
- [System handbook](./docs/handbook.md), [documentation from AL UI tests](./docs/al-ui-test-documentation.md), and [Code Graph](./docs/code-graph-markdown-design.md)
|
|
184
193
|
- [Agent integration and MCP](./docs/agent-integration.md)
|
|
185
194
|
- [CLI reference](./docs/cli-reference.md) and [troubleshooting](./docs/troubleshooting.md)
|
|
186
|
-
- Generated examples: [architecture report](./examples/report/README.md) and [user guides](./examples/docs/index.md)
|
|
195
|
+
- Generated examples: [architecture report](./examples/report/README.md), [system handbook](./examples/handbook/README.md), and [user guides](./examples/docs/index.md)
|
|
187
196
|
|
|
188
197
|
## AI agents and tools
|
|
189
198
|
|
|
@@ -194,8 +203,8 @@ bca mcp # MCP stdio server (also installed as bca-mcp)
|
|
|
194
203
|
|
|
195
204
|
Agents should read the contract first, pass arguments as arrays, parse stdout
|
|
196
205
|
only after a successful exit code, and preview changes with `--dry-run`. The
|
|
197
|
-
MCP server exposes inspect, check,
|
|
198
|
-
and update-check tools. `bca setup agent --agent claude|copilot|cursor` adds a
|
|
206
|
+
MCP server exposes inspect, check, architecture, report, handbook, diagram,
|
|
207
|
+
documentation, setup, run, and update-check tools. `bca setup agent --agent claude|copilot|cursor` adds a
|
|
199
208
|
`/bca-setup` command that lets your agent guide the setup. See
|
|
200
209
|
[agent integration](./docs/agent-integration.md).
|
|
201
210
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bc-atlas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "BC Atlas maps Microsoft Dynamics 365 Business Central AL projects: architecture diagrams, health checks, reports, and documentation generated from source.",
|
|
5
5
|
"homepage": "https://github.com/SchulzOli/BC-Atlas#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"src/",
|
|
20
20
|
"vendor/",
|
|
21
|
+
"schemas/",
|
|
21
22
|
".bca.example.json",
|
|
22
23
|
"CHANGELOG.md",
|
|
23
24
|
"LICENSE",
|
|
@@ -31,6 +32,7 @@
|
|
|
31
32
|
"docs": "node ./scripts/generate-docs.js",
|
|
32
33
|
"docs:check": "node ./scripts/generate-docs.js --check",
|
|
33
34
|
"examples": "node ./scripts/generate-examples.js",
|
|
35
|
+
"benchmark": "node ./scripts/benchmark.js",
|
|
34
36
|
"mcp": "node ./src/mcp.js",
|
|
35
37
|
"prepack": "npm run check && npm test",
|
|
36
38
|
"update:grammar": "node ./scripts/update-grammar.js",
|
|
@@ -81,7 +83,7 @@
|
|
|
81
83
|
"n3": "^2.13.12",
|
|
82
84
|
"opentype.js": "^2.0.0",
|
|
83
85
|
"rdfxml-streaming-parser": "^3.3.0",
|
|
84
|
-
"three": "^0.
|
|
85
|
-
"vitepress": "2.0.0-alpha.
|
|
86
|
+
"three": "^0.187.0",
|
|
87
|
+
"vitepress": "2.0.0-alpha.21"
|
|
86
88
|
}
|
|
87
89
|
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/SchulzOli/BC-Atlas/blob/main/schemas/bca.schema.json",
|
|
4
|
+
"title": "BC Atlas configuration (.bca.json)",
|
|
5
|
+
"description": "Settings for bca check, export, architecture, docs, and run. See docs/configuration.md.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"$schema": { "type": "string" },
|
|
9
|
+
"view": { "description": "Default diagram view.", "enum": ["project", "module", "object", "data", "call", "boundary", "contracts", "events", "ui", "workflow"] },
|
|
10
|
+
"projectRoot": { "description": "Root of the AL project, relative to this file.", "type": "string" },
|
|
11
|
+
"paths": { "description": "Analyze only these folders (globs allowed).", "type": "array", "items": { "type": "string" } },
|
|
12
|
+
"direction": { "enum": ["right", "down", "left", "up"] },
|
|
13
|
+
"title": { "type": "string" },
|
|
14
|
+
"groupBy": { "description": "Diagram grouping (not the architecture proposal; see architecture.proposal.groupBy).", "enum": ["namespace", "folder", "type", "role"] },
|
|
15
|
+
"roleMappings": { "description": "Role lanes for the project view: role name to selectors.", "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } } },
|
|
16
|
+
"namespaces": { "type": "array", "items": { "type": "string" } },
|
|
17
|
+
"include": { "type": "array", "items": { "type": "string" } },
|
|
18
|
+
"exclude": { "description": "Files to leave out of the analysis (globs).", "type": "array", "items": { "type": "string" } },
|
|
19
|
+
"moduleDepth": { "oneOf": [{ "const": "auto" }, { "type": "integer", "minimum": 1 }] },
|
|
20
|
+
"folderDepth": { "type": "integer", "minimum": 1 },
|
|
21
|
+
"includeUnresolvedCalls": { "type": "boolean" },
|
|
22
|
+
"maxEdges": { "type": "integer", "minimum": 1 },
|
|
23
|
+
"details": { "type": "boolean" },
|
|
24
|
+
"noExternal": { "type": "boolean" },
|
|
25
|
+
"sourceUrl": { "description": "Link template for source locations: {ref}, {file}, {line}.", "type": "string" },
|
|
26
|
+
"sourceRef": { "type": "string" },
|
|
27
|
+
"sourcePathPrefix": { "type": "string" },
|
|
28
|
+
"workflow": { "type": "object" },
|
|
29
|
+
"forbiddenDependencies": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"required": ["from", "to"],
|
|
34
|
+
"properties": {
|
|
35
|
+
"from": { "type": "string" },
|
|
36
|
+
"to": { "type": "string" },
|
|
37
|
+
"severity": { "enum": ["error", "warning", "info"] },
|
|
38
|
+
"message": { "type": "string" }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"architecture": { "$ref": "#/$defs/architecture" },
|
|
43
|
+
"check": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"properties": {
|
|
46
|
+
"failOn": { "enum": ["error", "warning", "info", "never"] },
|
|
47
|
+
"cycles": { "enum": ["error", "warning", "info", "off"] },
|
|
48
|
+
"maxFanIn": { "type": "integer", "minimum": 1 },
|
|
49
|
+
"maxFanOut": { "type": "integer", "minimum": 1 },
|
|
50
|
+
"maxComplexity": { "description": "high-complexity: procedures above this cyclomatic complexity (default 25).", "type": "integer", "minimum": 1 },
|
|
51
|
+
"severities": {
|
|
52
|
+
"description": "Severity of the quality rules: error, warning, info, or off.",
|
|
53
|
+
"type": "object",
|
|
54
|
+
"properties": {
|
|
55
|
+
"missing-data-classification": { "enum": ["error", "warning", "info", "off"], "default": "warning" },
|
|
56
|
+
"obsolete-without-tag": { "enum": ["error", "warning", "info", "off"], "default": "warning" },
|
|
57
|
+
"high-complexity": { "enum": ["error", "warning", "info", "off"], "default": "warning" },
|
|
58
|
+
"missing-tooltip": { "enum": ["error", "warning", "info", "off"], "default": "info" },
|
|
59
|
+
"obsolete-without-reason": { "enum": ["error", "warning", "info", "off"], "default": "info" },
|
|
60
|
+
"undocumented-public-api": { "enum": ["error", "warning", "info", "off"], "default": "info" }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"contractExpectations": { "type": "array" },
|
|
64
|
+
"contexts": { "type": "array" }
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"al": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"properties": {
|
|
70
|
+
"compiler": { "description": "auto, off, or a path to alc, al, or the AL extension folder.", "type": "string" },
|
|
71
|
+
"analyzers": { "type": "array", "items": { "type": "string" } },
|
|
72
|
+
"errorLog": { "type": "string" },
|
|
73
|
+
"callGraph": { "type": "boolean" },
|
|
74
|
+
"workspaceFile": { "type": "string" }
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"report": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"properties": {
|
|
80
|
+
"outputDir": { "type": "string" },
|
|
81
|
+
"views": { "type": "array", "items": { "type": "string" } },
|
|
82
|
+
"format": { "enum": ["svg", "d2"] },
|
|
83
|
+
"title": { "type": "string" },
|
|
84
|
+
"codegraph": { "type": "boolean" },
|
|
85
|
+
"handbook": { "description": "Also write the system handbook to <outputDir>/handbook.", "type": "boolean" },
|
|
86
|
+
"json": { "type": "boolean" }
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"codegraph": { "type": "object", "properties": { "outputDir": { "type": "string" } } },
|
|
90
|
+
"handbook": {
|
|
91
|
+
"description": "The system handbook (bca export --view handbook, the handbook task of bca run).",
|
|
92
|
+
"type": "object",
|
|
93
|
+
"properties": {
|
|
94
|
+
"outputDir": { "type": "string", "default": "docs/handbook" },
|
|
95
|
+
"title": { "type": "string" },
|
|
96
|
+
"language": { "description": "Language of the pages: en (default) or de (de-DE).", "type": "string" },
|
|
97
|
+
"catalog": { "description": "Folder of the object catalog that object names link to; bca run uses the codegraph task's folder when the same run writes it.", "type": "string" }
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"docs": { "type": "object" },
|
|
101
|
+
"automation": { "type": "object" }
|
|
102
|
+
},
|
|
103
|
+
"$defs": {
|
|
104
|
+
"selector": {
|
|
105
|
+
"description": "namespace:, folder:, file:, app:, module:, type:, object:type:name, id:from..to, or *; join with & so all must match.",
|
|
106
|
+
"type": "string"
|
|
107
|
+
},
|
|
108
|
+
"selectors": {
|
|
109
|
+
"oneOf": [
|
|
110
|
+
{ "$ref": "#/$defs/selector" },
|
|
111
|
+
{ "type": "array", "items": { "$ref": "#/$defs/selector" }, "minItems": 1 }
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
"relationKind": {
|
|
115
|
+
"enum": ["writes", "extends", "source", "relates", "implements", "calls", "runs", "part", "reads", "selects", "uses", "subscribes", "permits", "includes"]
|
|
116
|
+
},
|
|
117
|
+
"architecture": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"properties": {
|
|
120
|
+
"components": {
|
|
121
|
+
"type": "array",
|
|
122
|
+
"items": {
|
|
123
|
+
"type": "object",
|
|
124
|
+
"required": ["name", "match"],
|
|
125
|
+
"properties": {
|
|
126
|
+
"name": { "type": "string" },
|
|
127
|
+
"description": { "type": "string" },
|
|
128
|
+
"layer": { "type": "integer", "minimum": 0 },
|
|
129
|
+
"match": { "$ref": "#/$defs/selectors" },
|
|
130
|
+
"dependsOn": { "type": "array", "items": { "type": "string" } },
|
|
131
|
+
"exposes": { "$ref": "#/$defs/selectors" },
|
|
132
|
+
"maxObjects": { "type": "integer", "minimum": 1 }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"proposal": { "$ref": "#/$defs/proposal" },
|
|
137
|
+
"couplingWeights": {
|
|
138
|
+
"description": "How strongly each relation kind binds two objects (defaults: writes 5, extends 4, source 4, relates 3, implements 3, calls 2, runs 2, part 2, reads 2, selects 1.5, uses 1, subscribes 1, permits 0.1, includes 0.1). 0 drops a kind.",
|
|
139
|
+
"type": "object",
|
|
140
|
+
"propertyNames": { "$ref": "#/$defs/relationKind" },
|
|
141
|
+
"additionalProperties": { "type": "number", "minimum": 0 }
|
|
142
|
+
},
|
|
143
|
+
"allowSameLayer": { "type": "boolean" },
|
|
144
|
+
"strictLayers": { "type": "boolean" },
|
|
145
|
+
"maxObjects": { "type": "integer", "minimum": 1 },
|
|
146
|
+
"severity": { "enum": ["error", "warning", "info", "off"] },
|
|
147
|
+
"unassigned": { "enum": ["error", "warning", "info", "off"] },
|
|
148
|
+
"severities": { "type": "object", "additionalProperties": { "enum": ["error", "warning", "info", "off"] } },
|
|
149
|
+
"rules": { "type": "array" },
|
|
150
|
+
"baseline": { "type": "string" },
|
|
151
|
+
"surface": { "type": "string" }
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"proposal": {
|
|
155
|
+
"description": "What bca architecture --propose takes into account, and how. Options of the command override these.",
|
|
156
|
+
"type": "object",
|
|
157
|
+
"additionalProperties": false,
|
|
158
|
+
"properties": {
|
|
159
|
+
"$comment": { "type": "string" },
|
|
160
|
+
"groupBy": {
|
|
161
|
+
"description": "auto or coupling: the typed, weighted relations decide; namespace or folder: the code structure decides, objects without it follow their relations; module or app: one component each.",
|
|
162
|
+
"enum": ["auto", "coupling", "namespace", "folder", "module", "app"],
|
|
163
|
+
"default": "auto"
|
|
164
|
+
},
|
|
165
|
+
"depth": { "description": "With groupBy namespace or folder: segments per component; default: split until no component is too large.", "type": "integer", "minimum": 1 },
|
|
166
|
+
"minObjects": { "description": "Smaller groups join the component they depend on most.", "type": "integer", "minimum": 1, "default": 1 },
|
|
167
|
+
"startFrom": {
|
|
168
|
+
"description": "Existing structures that compete with the relations as a starting point. [] for relations only. The relations decide which survives.",
|
|
169
|
+
"type": "array",
|
|
170
|
+
"items": { "enum": ["namespace", "folder"] },
|
|
171
|
+
"uniqueItems": true,
|
|
172
|
+
"default": ["namespace", "folder"]
|
|
173
|
+
},
|
|
174
|
+
"ignore": {
|
|
175
|
+
"description": "Relation kinds that never shape a component (they still count as dependencies).",
|
|
176
|
+
"type": "array",
|
|
177
|
+
"items": { "$ref": "#/$defs/relationKind" },
|
|
178
|
+
"uniqueItems": true,
|
|
179
|
+
"default": ["permits", "includes"]
|
|
180
|
+
},
|
|
181
|
+
"granularity": { "description": "Above 1: more, smaller components; below 1: fewer, larger ones.", "type": "number", "exclusiveMinimum": 0, "default": 1 },
|
|
182
|
+
"appGranularity": { "description": "The same for app candidates (which components could become one app together).", "type": "number", "exclusiveMinimum": 0, "default": 0.3 },
|
|
183
|
+
"sharedCore": { "description": "Pull objects that many components use (setup tables, utilities) into a shared core.", "type": "boolean", "default": true },
|
|
184
|
+
"keep": {
|
|
185
|
+
"description": "Components you define yourself. Their objects are not clustered; the proposal arranges everything else around them.",
|
|
186
|
+
"type": "array",
|
|
187
|
+
"items": {
|
|
188
|
+
"type": "object",
|
|
189
|
+
"required": ["name", "match"],
|
|
190
|
+
"additionalProperties": false,
|
|
191
|
+
"properties": {
|
|
192
|
+
"name": { "type": "string" },
|
|
193
|
+
"match": { "$ref": "#/$defs/selectors" },
|
|
194
|
+
"description": { "type": "string" }
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
"exclude": {
|
|
199
|
+
"description": "Objects that do not shape components (for example type:permissionset or test codeunits). They join the component they are most coupled to afterwards.",
|
|
200
|
+
"$ref": "#/$defs/selectors"
|
|
201
|
+
},
|
|
202
|
+
"moves": {
|
|
203
|
+
"description": "Objects that belong elsewhere: at least minGain more coupling to another component than to their own; at most limit of them.",
|
|
204
|
+
"type": "object",
|
|
205
|
+
"additionalProperties": false,
|
|
206
|
+
"properties": {
|
|
207
|
+
"minGain": { "type": "number", "minimum": 0, "default": 2 },
|
|
208
|
+
"limit": { "type": "integer", "minimum": 0, "default": 50 }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|