@maggioli-design-system/magma-react 2.6.0 → 2.7.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/AGENTS.md +1 -1
- package/CHANGELOG.md +24 -0
- package/agents/assets.md +23 -9
- package/agents/conventions.md +2 -1
- package/agents/lint.md +37 -9
- package/agents/mcp.md +6 -2
- package/agents/reporting.md +53 -2
- package/package.json +2 -2
package/AGENTS.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
-->
|
|
6
6
|
# @maggioli-design-system/magma-react - agent install guide
|
|
7
7
|
|
|
8
|
-
> Version 2.
|
|
8
|
+
> Version 2.7.0. You (the agent) are installing Magma into THIS project. Do not
|
|
9
9
|
> assume the setup - detect it from the project, then ask the user only for what you
|
|
10
10
|
> cannot infer. The detailed steps live in [`agents/install.md`](agents/install.md)
|
|
11
11
|
> (this target) and [`agents/assets.md`](agents/assets.md) (shared styles, fonts,
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ package.
|
|
|
7
7
|
It is released together with `magma`, at the same version: the sections are the
|
|
8
8
|
releases of `magma`.
|
|
9
9
|
|
|
10
|
+
## [magma@2.7.0] - 2026-10-24
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- *(lint)* Spell multi-word Material slugs with hyphens, as iconsauce serves them
|
|
15
|
+
- *(lint)* Check_setup accepts every icon path and lint config its guides document
|
|
16
|
+
- *(lint)* Serialise every DTCG type of the token tools, keep the class of suggest_role
|
|
17
|
+
- *(lint)* No-internal-tokens reads the custom properties of Tailwind classes and @apply
|
|
18
|
+
|
|
19
|
+
### Build
|
|
20
|
+
|
|
21
|
+
- *(magma)* Keep test fixtures out of the release package map
|
|
22
|
+
|
|
23
|
+
### Documentation
|
|
24
|
+
|
|
25
|
+
- *(magma)* Write where each answer of the lint and the MCP server comes from
|
|
26
|
+
- *(magma)* Route agents to the data contracts, stop loading the consumer guides
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
- *(lint)* Ship the MCP tools as data, describe the Stylelint rules, link the release
|
|
31
|
+
- *(lint)* Lead the agent to propose an issue when the MCP server lacks a tool
|
|
32
|
+
- *(lint)* Read classes in clsx(), ternaries, [ngClass] and @apply, as the codemod does
|
|
33
|
+
|
|
10
34
|
## [magma@2.6.0] - 2026-10-24
|
|
11
35
|
|
|
12
36
|
### Bug Fixes
|
package/agents/assets.md
CHANGED
|
@@ -154,6 +154,12 @@ with its icon set, and each set comes from its own package, with its own layout:
|
|
|
154
154
|
| `mdi/<name>` | Material Design Icons | `@mdi/svg` | `svg/<name>.svg` |
|
|
155
155
|
| `mgg/<name>` | Maggioli | `@maggioli-design-system/svg-icons` | `dist/svg/<name>.svg` |
|
|
156
156
|
|
|
157
|
+
The slugs are the ones iconsauce writes (Route 1), so a Material slug is not the name of
|
|
158
|
+
its folder: a multi-word name takes hyphens in the slug and underscores in the package
|
|
159
|
+
(`mi/baseline/check-circle` is `svg/check_circle/baseline.svg`), and the variants are
|
|
160
|
+
`baseline`, `outline`, `round` and `sharp`. The package's `twotone.svg` has no slug: iconsauce
|
|
161
|
+
never serves it, and a slug spelled with the folder's underscores renders nothing.
|
|
162
|
+
|
|
157
163
|
Magma ships only the `mgg/` set, and none of these packages is a dependency of `magma`,
|
|
158
164
|
`magma-react` or `magma-angular`: the route you pick installs what it needs. Copying the
|
|
159
165
|
`svg-icons` folder as it is does NOT follow the contract: its files sit directly in
|
|
@@ -200,8 +206,9 @@ in full, or list the computed ones in a file that `content` reads.
|
|
|
200
206
|
|
|
201
207
|
### Route 2: serve the files yourself
|
|
202
208
|
|
|
203
|
-
One renaming step: `@material-icons/svg` stores
|
|
204
|
-
wants `mi
|
|
209
|
+
One renaming step: `@material-icons/svg` stores `check_circle/baseline.svg`, while the slug
|
|
210
|
+
wants `mi/baseline/check-circle` (the contract above). `mdi/` and `mgg/` are plain folder
|
|
211
|
+
copies. This script covers
|
|
205
212
|
the three sets with Node built-ins only, so it fits any bundler:
|
|
206
213
|
|
|
207
214
|
```bash
|
|
@@ -212,7 +219,7 @@ npm i -D @maggioli-design-system/svg-icons @material-icons/svg @mdi/svg
|
|
|
212
219
|
// scripts/copy-icons.mjs
|
|
213
220
|
// Copies Magma's icon sets where mds-icon fetches them: <OUT>/<slug>.svg.
|
|
214
221
|
// node scripts/copy-icons.mjs icons.json only the slugs listed in icons.json
|
|
215
|
-
// node scripts/copy-icons.mjs every icon of the three sets (
|
|
222
|
+
// node scripts/copy-icons.mjs every icon of the three sets (16,530 files, 64 MB)
|
|
216
223
|
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync } from 'node:fs';
|
|
217
224
|
import { createRequire } from 'node:module';
|
|
218
225
|
import { dirname, join } from 'node:path';
|
|
@@ -220,14 +227,18 @@ import { dirname, join } from 'node:path';
|
|
|
220
227
|
const OUT = 'public/svg'; // served at /svg/ by Vite, Next.js and the Angular CLI
|
|
221
228
|
const require = createRequire(import.meta.url);
|
|
222
229
|
const root = (pkg) => dirname(require.resolve(`${pkg}/package.json`));
|
|
223
|
-
const MI = join(root('@material-icons/svg'), 'svg'); // <
|
|
230
|
+
const MI = join(root('@material-icons/svg'), 'svg'); // <name_with_underscores>/<variant>.svg
|
|
224
231
|
const MDI = join(root('@mdi/svg'), 'svg'); // <name>.svg
|
|
225
232
|
const MGG = join(root('@maggioli-design-system/svg-icons'), 'dist/svg'); // <name>.svg
|
|
226
233
|
|
|
234
|
+
// The Material variants iconsauce serves; a slug spells the folder's underscores as hyphens.
|
|
235
|
+
const MI_VARIANTS = ['baseline', 'outline', 'round', 'sharp'];
|
|
236
|
+
|
|
227
237
|
// Source file of a slug: mi/<variant>/<name>, mdi/<name>, mgg/<name>.
|
|
228
238
|
function source(slug) {
|
|
229
239
|
const [set, ...rest] = slug.split('/');
|
|
230
|
-
if (set === 'mi' && rest.length === 2
|
|
240
|
+
if (set === 'mi' && rest.length === 2 && MI_VARIANTS.includes(rest[0]) && !rest[1].includes('_'))
|
|
241
|
+
return join(MI, rest[1].replaceAll('-', '_'), `${rest[0]}.svg`);
|
|
231
242
|
if (set === 'mdi' && rest.length === 1) return join(MDI, `${rest[0]}.svg`);
|
|
232
243
|
if (set === 'mgg' && rest.length === 1) return join(MGG, `${rest[0]}.svg`);
|
|
233
244
|
throw new Error(`Not a Magma icon slug: ${slug}`);
|
|
@@ -236,7 +247,9 @@ function source(slug) {
|
|
|
236
247
|
function allSlugs() {
|
|
237
248
|
const names = (dir) => readdirSync(dir).map((file) => file.replace(/\.svg$/, ''));
|
|
238
249
|
return [
|
|
239
|
-
...readdirSync(MI).flatMap((
|
|
250
|
+
...readdirSync(MI).flatMap((folder) =>
|
|
251
|
+
MI_VARIANTS.map((variant) => `mi/${variant}/${folder.replaceAll('_', '-')}`),
|
|
252
|
+
),
|
|
240
253
|
...names(MDI).map((name) => `mdi/${name}`),
|
|
241
254
|
...names(MGG).map((name) => `mgg/${name}`),
|
|
242
255
|
];
|
|
@@ -256,7 +269,7 @@ console.log(`${slugs.length} icons in ${OUT}/`);
|
|
|
256
269
|
`icons.json` lists the slugs the app uses:
|
|
257
270
|
|
|
258
271
|
```json
|
|
259
|
-
["mi/baseline/email", "mi/
|
|
272
|
+
["mi/baseline/email", "mi/outline/check-circle", "mdi/github", "mgg/abitazione-principale"]
|
|
260
273
|
```
|
|
261
274
|
|
|
262
275
|
```json
|
|
@@ -270,7 +283,7 @@ console.log(`${slugs.length} icons in ${OUT}/`);
|
|
|
270
283
|
A slug that does not exist stops the script with an error. A slug used in the code but
|
|
271
284
|
missing from `icons.json` gives a 404 at runtime: iconsauce avoids that by reading the
|
|
272
285
|
sources. Without `icons.json` the script copies every icon of the three sets, all of
|
|
273
|
-
them deployed:
|
|
286
|
+
them deployed: 16,530 files and 64 MB (`mi` 34 MB in four variants, `mdi` 29 MB, `mgg`
|
|
274
287
|
1.3 MB).
|
|
275
288
|
|
|
276
289
|
### Only the `mgg/` set
|
|
@@ -409,7 +422,8 @@ Known limits, nothing to configure:
|
|
|
409
422
|
- [ ] `@fontsource` fonts installed and imported in the `vendor` layer
|
|
410
423
|
- [ ] Every icon slug the app uses served at `<mdsIconSvgPath><slug>.svg` (iconsauce or
|
|
411
424
|
the copy script, run before dev and build, output folder out of git)
|
|
412
|
-
- [ ]
|
|
425
|
+
- [ ] That public path set before hydration (`IconsSetService.setSvgPath()` or the
|
|
426
|
+
`mdsIconSvgPath` key of `sessionStorage`)
|
|
413
427
|
- [ ] (optional) `identity` installed if brand assets are used
|
|
414
428
|
- [ ] Components registered per your target track
|
|
415
429
|
- [ ] (VS Code) the editor keys merged into `.vscode/settings.json` and `extensions.json`;
|
package/agents/conventions.md
CHANGED
|
@@ -121,7 +121,8 @@ Maggioli):
|
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
`mds-icon` fetches `<mdsIconSvgPath><slug>.svg`; the path is configured once at startup
|
|
124
|
-
(see [`assets.md`](assets.md)): `
|
|
124
|
+
(see [`assets.md`](assets.md)): `IconsSetService.setSvgPath('/svg/')`, or
|
|
125
|
+
`sessionStorage.setItem('mdsIconSvgPath', '/svg/')`.
|
|
125
126
|
|
|
126
127
|
## Accessibility
|
|
127
128
|
|
package/agents/lint.md
CHANGED
|
@@ -55,8 +55,9 @@ export default [
|
|
|
55
55
|
];
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
The rules read both `<mds-button>` and the wrappers of `magma-react` (`<MdsButton>`), and
|
|
59
|
-
`className`
|
|
58
|
+
The rules read both `<mds-button>` and the wrappers of `magma-react` (`<MdsButton>`), and the
|
|
59
|
+
classes of a `className` wherever its expression writes them, `clsx()` and ternaries included
|
|
60
|
+
(see [`no-raw-palette-classes`](#no-raw-palette-classes)).
|
|
60
61
|
|
|
61
62
|
### Angular
|
|
62
63
|
|
|
@@ -111,7 +112,7 @@ component may change in any release. When a rule is wrong about Magma itself, re
|
|
|
111
112
|
| [`valid-attribute-values`](#valid-attribute-values) | ESLint | error | error |
|
|
112
113
|
| [`no-false-boolean`](#no-false-boolean) | ESLint | error | error |
|
|
113
114
|
| [`accessible-name`](#accessible-name) | ESLint | error | error |
|
|
114
|
-
| [`no-raw-palette-classes`](#no-raw-palette-classes) | ESLint | warn | error |
|
|
115
|
+
| [`no-raw-palette-classes`](#no-raw-palette-classes) | ESLint, Stylelint | warn | error |
|
|
115
116
|
| [`no-color-scheme-override`](#no-color-scheme-override) | Stylelint | error | error |
|
|
116
117
|
| [`no-raw-color`](#no-raw-color) | Stylelint | warning | error |
|
|
117
118
|
| [`no-internal-tokens`](#no-internal-tokens) | ESLint, Stylelint | warn | error |
|
|
@@ -190,8 +191,30 @@ read through: `dark:hover:bg-white/50` is `bg-white`.
|
|
|
190
191
|
```
|
|
191
192
|
|
|
192
193
|
Not reported: `label-*` and `brand-*`, for colour that encodes data, and the seed of a tone,
|
|
193
|
-
the pure extreme of the mode.
|
|
194
|
-
|
|
194
|
+
the pure extreme of the mode.
|
|
195
|
+
|
|
196
|
+
A class is read wherever the project writes one, in the forms the codemod migrates:
|
|
197
|
+
|
|
198
|
+
- the `class` attribute of HTML and Angular templates;
|
|
199
|
+
- React: every string in a `className` (or `class`) expression, the arguments and object keys
|
|
200
|
+
of `clsx()` or `classnames()`, both branches of a ternary, a `||` fallback, and the fixed
|
|
201
|
+
parts of a template literal;
|
|
202
|
+
- Angular: the key of `[class.<name>]` and the quoted strings of `[ngClass]`, `[class]` and
|
|
203
|
+
`[attr.class]`;
|
|
204
|
+
- Stylelint: the classes of `@apply`.
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
// INCORRECT
|
|
208
|
+
<div className={clsx('p-400', active && 'bg-white')} />
|
|
209
|
+
|
|
210
|
+
// CORRECT
|
|
211
|
+
<div className={clsx('p-400', active && 'bg-surface-raised')} />
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Not read: a class put together at run time (`bg-${tone}-03`, of which only the fixed parts are
|
|
215
|
+
read), classes kept in a variable outside the attribute (`const card = clsx(...)`), and HTML
|
|
216
|
+
written as a string in a script (`el.innerHTML = ...`). A string compared in a condition is
|
|
217
|
+
read too, and reported only when it is itself a palette class.
|
|
195
218
|
|
|
196
219
|
### no-color-scheme-override
|
|
197
220
|
|
|
@@ -240,9 +263,13 @@ Any other colour that is not a role keeps its literal under a disable comment th
|
|
|
240
263
|
An `--mds-*` custom property, set or read, that no component promises. A component's
|
|
241
264
|
`AGENTS.md` lists its public custom properties, the only ones a product sets; the others are
|
|
242
265
|
internal, its implementation, and may change or go in any release without notice. A name no
|
|
243
|
-
component documents is reported too. Stylelint reads the stylesheets
|
|
244
|
-
inline styles of the templates
|
|
245
|
-
object, an Angular `[style.--mds-<name>]` binding
|
|
266
|
+
component documents is reported too. Stylelint reads the stylesheets, the classes of `@apply`
|
|
267
|
+
included; ESLint reads the inline styles of the templates (a `style` attribute, a React
|
|
268
|
+
`style={{ '--mds-<name>': ... }}` object, an Angular `[style.--mds-<name>]` binding) and their
|
|
269
|
+
Tailwind classes, wherever [`no-raw-palette-classes`](#no-raw-palette-classes) reads a class,
|
|
270
|
+
through variants and `!`: an arbitrary property that sets one
|
|
271
|
+
(`[--mds-<name>:<value>]`, on the component or on a parent that sets it for its descendants)
|
|
272
|
+
and an arbitrary value that reads one (`bg-[var(--mds-<name>)]`, `bg-(--mds-<name>)`).
|
|
246
273
|
|
|
247
274
|
```css
|
|
248
275
|
/* INCORRECT: internal, it may change in any release */
|
|
@@ -266,5 +293,6 @@ The rules need no settings: they read the `documentation.json` beside them in th
|
|
|
266
293
|
`magma`, and the tokens of the `design-tokens` and `styles` it depends on. To check against
|
|
267
294
|
other files, set their paths under `settings.magma` in the ESLint configuration (relative to
|
|
268
295
|
`root`, the project by default): `documentation`, `tokens`, `consumption`. The Stylelint rules
|
|
269
|
-
take `root` and `documentation`
|
|
296
|
+
take the paths they read as secondary options, `root` and `documentation` for `no-internal-tokens`
|
|
297
|
+
and `no-raw-color`, `root`, `tokens` and `consumption` for `no-raw-palette-classes`:
|
|
270
298
|
`'magma/no-internal-tokens': [true, { documentation: './documentation.json' }]`.
|
package/agents/mcp.md
CHANGED
|
@@ -84,7 +84,7 @@ client starts servers elsewhere than the project's root, pass it:
|
|
|
84
84
|
| `get_component` | the API of one component: props with their values and default, events, methods, slots, parts, public CSS custom properties | reading its `AGENTS.md` |
|
|
85
85
|
| `get_usage` | how HTML, React or Angular writes it: import, props, events (`onMdsInputChange`, `(mdsInputChange)`) | guessing the names |
|
|
86
86
|
| `list_tokens` | the role for a need ("secondary text"), with its value and class | reading [`color.md`](color.md) |
|
|
87
|
-
| `suggest_role` | the role for a colour, a raw class or a palette step | picking a role by eye |
|
|
87
|
+
| `suggest_role` | the role for a colour, a raw class or a palette step, as a class of the same utility (`shadow-*/80` stays a shadow class) | picking a role by eye |
|
|
88
88
|
| `explain_class` | what a class does with the Magma theme | the trap of the scale: `p-4` is 0.01rem, `p-400` is 1rem |
|
|
89
89
|
| `find_icon` | a slug that exists, by meaning, or whether a slug exists | an `icon="..."` that renders nothing |
|
|
90
90
|
| `get_guide` | one section of a guide | reading the whole file |
|
|
@@ -92,7 +92,8 @@ client starts servers elsewhere than the project's root, pass it:
|
|
|
92
92
|
| `check_setup` | what the Magma integration of the project misses | checking the install steps by hand |
|
|
93
93
|
|
|
94
94
|
`check_markup` uses the ESLint, Stylelint and template parsers the project installed with
|
|
95
|
-
the lint ([`lint.md`](lint.md)).
|
|
95
|
+
the lint ([`lint.md`](lint.md)). The same definitions, for a tool that documents them, are in
|
|
96
|
+
`@maggioli-design-system/magma/dist/lint/mcp/tools.json`: what `tools/list` answers.
|
|
96
97
|
|
|
97
98
|
## When to call them
|
|
98
99
|
|
|
@@ -101,3 +102,6 @@ the lint ([`lint.md`](lint.md)).
|
|
|
101
102
|
- Before an icon: `find_icon`.
|
|
102
103
|
- After writing: `check_markup`, then the project's lint ([`lint.md`](lint.md)).
|
|
103
104
|
- After the bootstrap, or when something does not render: `check_setup`.
|
|
105
|
+
- When no tool gives you what the task needs, or an answer carries `gap`: tell the user,
|
|
106
|
+
and at the end of the task propose an issue on Magma
|
|
107
|
+
([`reporting.md`](reporting.md), "A tool or an answer the MCP server is missing").
|
package/agents/reporting.md
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
> Scope: you are working in a project that uses Magma and you hit a problem that is
|
|
9
9
|
> Magma's, not the project's: a component that misbehaves, a guide that is wrong, a
|
|
10
|
-
> missing token or utility, a packaging or install issue
|
|
11
|
-
> the Magma
|
|
10
|
+
> missing token or utility, a packaging or install issue, or something you needed that
|
|
11
|
+
> the Magma MCP server does not answer (section 7). This is how to report it to the
|
|
12
|
+
> Magma repository, `magma-design-system/magma`, labelled with the project it comes
|
|
12
13
|
> from, so the maintainers can tell which project reported what.
|
|
13
14
|
|
|
14
15
|
## 1. Make sure it is Magma's
|
|
@@ -125,3 +126,53 @@ the title, the labels and the body to open it by hand at
|
|
|
125
126
|
|
|
126
127
|
Then give the user the issue URL, and leave a comment in the project next to the
|
|
127
128
|
workaround that links it, so the workaround can go once the fix ships.
|
|
129
|
+
|
|
130
|
+
## 7. A tool or an answer the MCP server is missing
|
|
131
|
+
|
|
132
|
+
The tools of the Magma MCP server ([`mcp.md`](mcp.md)) are there so you never read the
|
|
133
|
+
installed files by hand or guess. When one of them could not give you what the task
|
|
134
|
+
needed, Magma wants to know: the next tool or field comes from these reports. It is a gap
|
|
135
|
+
when:
|
|
136
|
+
|
|
137
|
+
- no tool covers the question, and you answered it by reading Magma's files
|
|
138
|
+
(`documentation.json`, the token data, the guides) or by guessing;
|
|
139
|
+
- a tool said Magma has nothing for a well-formed question: its answer carries `gap`, or
|
|
140
|
+
its error says it does not know;
|
|
141
|
+
- a tool answered, but not with what the task needed: a field it does not return, a
|
|
142
|
+
filter or an argument it does not take.
|
|
143
|
+
|
|
144
|
+
It is not a gap when the answer is right but not the one you hoped for, when your own
|
|
145
|
+
input was wrong (an unknown tag, a missing argument), or when the question is about the
|
|
146
|
+
project rather than Magma.
|
|
147
|
+
|
|
148
|
+
Tell the user when it happens, carry on with the task, and at the end propose one issue
|
|
149
|
+
per missing capability, gathered from the whole task. Follow steps 2, 3, 4 and 6 (look
|
|
150
|
+
for an existing issue, ask before opening it, the labels, create it), with `feature`,
|
|
151
|
+
`prg-stencil` (the server ships inside `magma`) and the project's `prd-*` label, and this
|
|
152
|
+
title and body instead of the ones of step 5. Title: `magma-mcp: <what is missing>`, e.g.
|
|
153
|
+
`magma-mcp: find_component cannot filter by category`. Body:
|
|
154
|
+
|
|
155
|
+
```markdown
|
|
156
|
+
## Need
|
|
157
|
+
|
|
158
|
+
What the task needed to know or to do, in one sentence.
|
|
159
|
+
|
|
160
|
+
## What the server answered
|
|
161
|
+
|
|
162
|
+
The tool you called and its arguments, and what it returned; or that no tool covers it.
|
|
163
|
+
|
|
164
|
+
## What I did instead
|
|
165
|
+
|
|
166
|
+
Read a file by hand, guessed, asked the user, and what it cost.
|
|
167
|
+
|
|
168
|
+
## Proposal
|
|
169
|
+
|
|
170
|
+
The tool, argument or field that would have answered it, if you have one in mind.
|
|
171
|
+
|
|
172
|
+
## Versions
|
|
173
|
+
|
|
174
|
+
- @maggioli-design-system/magma: <installed version>
|
|
175
|
+
- Client: <e.g. Claude Code, VS Code, Cursor>
|
|
176
|
+
|
|
177
|
+
Found in <project> (<repository>).
|
|
178
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maggioli-design-system/magma-react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/components.js",
|
|
6
6
|
"module": "dist/components.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@maggioli-design-system/magma": "2.
|
|
38
|
+
"@maggioli-design-system/magma": "2.7.0",
|
|
39
39
|
"@stencil/react-output-target": "1.6.5"
|
|
40
40
|
},
|
|
41
41
|
"repository": {
|