mlola-ui 1.0.3 → 1.0.4
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/README.md +29 -2
- package/package.json +1 -1
- package/registry/agents.json +419 -0
- package/registry/agents.md +453 -0
- package/registry/assets.json +734 -110
- package/registry/catalog.json +1187 -0
- package/registry/contract.json +1064 -0
- package/registry/index.json +37 -37
- package/src/agents.js +119 -0
- package/src/cli.js +27 -2
- package/src/knowledge.js +235 -0
- package/src/mcp.js +241 -0
package/registry/index.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "./schema/registry-index.schema.json",
|
|
3
3
|
"schemaVersion": 2,
|
|
4
4
|
"name": "mlola-ui",
|
|
5
|
-
"version": "1.0.
|
|
5
|
+
"version": "1.0.4",
|
|
6
6
|
"homepage": "https://ui.mlola.com",
|
|
7
7
|
"themeContract": {
|
|
8
8
|
"attribute": "data-theme",
|
|
@@ -179,8 +179,8 @@
|
|
|
179
179
|
},
|
|
180
180
|
"registryDependencies": [],
|
|
181
181
|
"engineDependencies": {
|
|
182
|
-
"@mlola-ui/behavior": "^1.0.
|
|
183
|
-
"@mlola-ui/icons": "^1.0.
|
|
182
|
+
"@mlola-ui/behavior": "^1.0.4",
|
|
183
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
184
184
|
},
|
|
185
185
|
"files": [
|
|
186
186
|
{
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
},
|
|
237
237
|
"registryDependencies": [],
|
|
238
238
|
"engineDependencies": {
|
|
239
|
-
"@mlola-ui/icons": "^1.0.
|
|
239
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
240
240
|
},
|
|
241
241
|
"files": [
|
|
242
242
|
{
|
|
@@ -352,7 +352,7 @@
|
|
|
352
352
|
},
|
|
353
353
|
"registryDependencies": [],
|
|
354
354
|
"engineDependencies": {
|
|
355
|
-
"@mlola-ui/icons": "^1.0.
|
|
355
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
356
356
|
},
|
|
357
357
|
"files": [
|
|
358
358
|
{
|
|
@@ -401,7 +401,7 @@
|
|
|
401
401
|
},
|
|
402
402
|
"registryDependencies": [],
|
|
403
403
|
"engineDependencies": {
|
|
404
|
-
"@mlola-ui/icons": "^1.0.
|
|
404
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
405
405
|
},
|
|
406
406
|
"files": [
|
|
407
407
|
{
|
|
@@ -463,7 +463,7 @@
|
|
|
463
463
|
},
|
|
464
464
|
"registryDependencies": [],
|
|
465
465
|
"engineDependencies": {
|
|
466
|
-
"@mlola-ui/motion": "^1.0.
|
|
466
|
+
"@mlola-ui/motion": "^1.0.4"
|
|
467
467
|
},
|
|
468
468
|
"files": [
|
|
469
469
|
{
|
|
@@ -567,8 +567,8 @@
|
|
|
567
567
|
},
|
|
568
568
|
"registryDependencies": [],
|
|
569
569
|
"engineDependencies": {
|
|
570
|
-
"@mlola-ui/behavior": "^1.0.
|
|
571
|
-
"@mlola-ui/icons": "^1.0.
|
|
570
|
+
"@mlola-ui/behavior": "^1.0.4",
|
|
571
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
572
572
|
},
|
|
573
573
|
"files": [
|
|
574
574
|
{
|
|
@@ -618,7 +618,7 @@
|
|
|
618
618
|
},
|
|
619
619
|
"registryDependencies": [],
|
|
620
620
|
"engineDependencies": {
|
|
621
|
-
"@mlola-ui/icons": "^1.0.
|
|
621
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
622
622
|
},
|
|
623
623
|
"files": [
|
|
624
624
|
{
|
|
@@ -670,7 +670,7 @@
|
|
|
670
670
|
"modal"
|
|
671
671
|
],
|
|
672
672
|
"engineDependencies": {
|
|
673
|
-
"@mlola-ui/icons": "^1.0.
|
|
673
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
674
674
|
},
|
|
675
675
|
"files": [
|
|
676
676
|
{
|
|
@@ -732,8 +732,8 @@
|
|
|
732
732
|
},
|
|
733
733
|
"registryDependencies": [],
|
|
734
734
|
"engineDependencies": {
|
|
735
|
-
"@mlola-ui/behavior": "^1.0.
|
|
736
|
-
"@mlola-ui/icons": "^1.0.
|
|
735
|
+
"@mlola-ui/behavior": "^1.0.4",
|
|
736
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
737
737
|
},
|
|
738
738
|
"files": [
|
|
739
739
|
{
|
|
@@ -784,7 +784,7 @@
|
|
|
784
784
|
"input"
|
|
785
785
|
],
|
|
786
786
|
"engineDependencies": {
|
|
787
|
-
"@mlola-ui/icons": "^1.0.
|
|
787
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
788
788
|
},
|
|
789
789
|
"files": [
|
|
790
790
|
{
|
|
@@ -980,8 +980,8 @@
|
|
|
980
980
|
},
|
|
981
981
|
"registryDependencies": [],
|
|
982
982
|
"engineDependencies": {
|
|
983
|
-
"@mlola-ui/behavior": "^1.0.
|
|
984
|
-
"@mlola-ui/icons": "^1.0.
|
|
983
|
+
"@mlola-ui/behavior": "^1.0.4",
|
|
984
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
985
985
|
},
|
|
986
986
|
"files": [
|
|
987
987
|
{
|
|
@@ -1086,7 +1086,7 @@
|
|
|
1086
1086
|
},
|
|
1087
1087
|
"registryDependencies": [],
|
|
1088
1088
|
"engineDependencies": {
|
|
1089
|
-
"@mlola-ui/icons": "^1.0.
|
|
1089
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
1090
1090
|
},
|
|
1091
1091
|
"files": [
|
|
1092
1092
|
{
|
|
@@ -1394,7 +1394,7 @@
|
|
|
1394
1394
|
},
|
|
1395
1395
|
"registryDependencies": [],
|
|
1396
1396
|
"engineDependencies": {
|
|
1397
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1397
|
+
"@mlola-ui/behavior": "^1.0.4"
|
|
1398
1398
|
},
|
|
1399
1399
|
"files": [
|
|
1400
1400
|
{
|
|
@@ -1448,8 +1448,8 @@
|
|
|
1448
1448
|
},
|
|
1449
1449
|
"registryDependencies": [],
|
|
1450
1450
|
"engineDependencies": {
|
|
1451
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1452
|
-
"@mlola-ui/icons": "^1.0.
|
|
1451
|
+
"@mlola-ui/behavior": "^1.0.4",
|
|
1452
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
1453
1453
|
},
|
|
1454
1454
|
"files": [
|
|
1455
1455
|
{
|
|
@@ -1520,8 +1520,8 @@
|
|
|
1520
1520
|
},
|
|
1521
1521
|
"registryDependencies": [],
|
|
1522
1522
|
"engineDependencies": {
|
|
1523
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1524
|
-
"@mlola-ui/icons": "^1.0.
|
|
1523
|
+
"@mlola-ui/behavior": "^1.0.4",
|
|
1524
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
1525
1525
|
},
|
|
1526
1526
|
"files": [
|
|
1527
1527
|
{
|
|
@@ -1628,7 +1628,7 @@
|
|
|
1628
1628
|
},
|
|
1629
1629
|
"registryDependencies": [],
|
|
1630
1630
|
"engineDependencies": {
|
|
1631
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1631
|
+
"@mlola-ui/behavior": "^1.0.4"
|
|
1632
1632
|
},
|
|
1633
1633
|
"files": [
|
|
1634
1634
|
{
|
|
@@ -1735,7 +1735,7 @@
|
|
|
1735
1735
|
},
|
|
1736
1736
|
"registryDependencies": [],
|
|
1737
1737
|
"engineDependencies": {
|
|
1738
|
-
"@mlola-ui/behavior": "^1.0.
|
|
1738
|
+
"@mlola-ui/behavior": "^1.0.4"
|
|
1739
1739
|
},
|
|
1740
1740
|
"files": [
|
|
1741
1741
|
{
|
|
@@ -1837,7 +1837,7 @@
|
|
|
1837
1837
|
},
|
|
1838
1838
|
"registryDependencies": [],
|
|
1839
1839
|
"engineDependencies": {
|
|
1840
|
-
"@mlola-ui/icons": "^1.0.
|
|
1840
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
1841
1841
|
},
|
|
1842
1842
|
"files": [
|
|
1843
1843
|
{
|
|
@@ -1893,7 +1893,7 @@
|
|
|
1893
1893
|
},
|
|
1894
1894
|
"registryDependencies": [],
|
|
1895
1895
|
"engineDependencies": {
|
|
1896
|
-
"@mlola-ui/icons": "^1.0.
|
|
1896
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
1897
1897
|
},
|
|
1898
1898
|
"files": [
|
|
1899
1899
|
{
|
|
@@ -2102,7 +2102,7 @@
|
|
|
2102
2102
|
},
|
|
2103
2103
|
"registryDependencies": [],
|
|
2104
2104
|
"engineDependencies": {
|
|
2105
|
-
"@mlola-ui/icons": "^1.0.
|
|
2105
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2106
2106
|
},
|
|
2107
2107
|
"files": [
|
|
2108
2108
|
{
|
|
@@ -2161,7 +2161,7 @@
|
|
|
2161
2161
|
"popover"
|
|
2162
2162
|
],
|
|
2163
2163
|
"engineDependencies": {
|
|
2164
|
-
"@mlola-ui/icons": "^1.0.
|
|
2164
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2165
2165
|
},
|
|
2166
2166
|
"files": [
|
|
2167
2167
|
{
|
|
@@ -2219,7 +2219,7 @@
|
|
|
2219
2219
|
"popover"
|
|
2220
2220
|
],
|
|
2221
2221
|
"engineDependencies": {
|
|
2222
|
-
"@mlola-ui/icons": "^1.0.
|
|
2222
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2223
2223
|
},
|
|
2224
2224
|
"files": [
|
|
2225
2225
|
{
|
|
@@ -2383,7 +2383,7 @@
|
|
|
2383
2383
|
"input"
|
|
2384
2384
|
],
|
|
2385
2385
|
"engineDependencies": {
|
|
2386
|
-
"@mlola-ui/icons": "^1.0.
|
|
2386
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2387
2387
|
},
|
|
2388
2388
|
"files": [
|
|
2389
2389
|
{
|
|
@@ -2448,7 +2448,7 @@
|
|
|
2448
2448
|
"input"
|
|
2449
2449
|
],
|
|
2450
2450
|
"engineDependencies": {
|
|
2451
|
-
"@mlola-ui/icons": "^1.0.
|
|
2451
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2452
2452
|
},
|
|
2453
2453
|
"files": [
|
|
2454
2454
|
{
|
|
@@ -2500,7 +2500,7 @@
|
|
|
2500
2500
|
"input"
|
|
2501
2501
|
],
|
|
2502
2502
|
"engineDependencies": {
|
|
2503
|
-
"@mlola-ui/icons": "^1.0.
|
|
2503
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2504
2504
|
},
|
|
2505
2505
|
"files": [
|
|
2506
2506
|
{
|
|
@@ -2560,7 +2560,7 @@
|
|
|
2560
2560
|
"popover"
|
|
2561
2561
|
],
|
|
2562
2562
|
"engineDependencies": {
|
|
2563
|
-
"@mlola-ui/icons": "^1.0.
|
|
2563
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2564
2564
|
},
|
|
2565
2565
|
"files": [
|
|
2566
2566
|
{
|
|
@@ -2616,7 +2616,7 @@
|
|
|
2616
2616
|
},
|
|
2617
2617
|
"registryDependencies": [],
|
|
2618
2618
|
"engineDependencies": {
|
|
2619
|
-
"@mlola-ui/icons": "^1.0.
|
|
2619
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2620
2620
|
},
|
|
2621
2621
|
"files": [
|
|
2622
2622
|
{
|
|
@@ -2719,7 +2719,7 @@
|
|
|
2719
2719
|
},
|
|
2720
2720
|
"registryDependencies": [],
|
|
2721
2721
|
"engineDependencies": {
|
|
2722
|
-
"@mlola-ui/icons": "^1.0.
|
|
2722
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2723
2723
|
},
|
|
2724
2724
|
"files": [
|
|
2725
2725
|
{
|
|
@@ -2840,7 +2840,7 @@
|
|
|
2840
2840
|
},
|
|
2841
2841
|
"registryDependencies": [],
|
|
2842
2842
|
"engineDependencies": {
|
|
2843
|
-
"@mlola-ui/icons": "^1.0.
|
|
2843
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2844
2844
|
},
|
|
2845
2845
|
"files": [
|
|
2846
2846
|
{
|
|
@@ -2905,7 +2905,7 @@
|
|
|
2905
2905
|
"sheet"
|
|
2906
2906
|
],
|
|
2907
2907
|
"engineDependencies": {
|
|
2908
|
-
"@mlola-ui/icons": "^1.0.
|
|
2908
|
+
"@mlola-ui/icons": "^1.0.4"
|
|
2909
2909
|
},
|
|
2910
2910
|
"files": [
|
|
2911
2911
|
{
|
package/src/agents.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { designGuide } from "./knowledge.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Tells the project's coding agents that the UI is Mlola, where the design
|
|
7
|
+
* language is written down, and how to ask about it, so an assistant builds
|
|
8
|
+
* with Mlola without being reminded:
|
|
9
|
+
*
|
|
10
|
+
* - `mlola.agents.md` the design guide: classes, tokens, rules (refreshed)
|
|
11
|
+
* - `AGENTS.md` a short section, between markers, read by most agents
|
|
12
|
+
* - `CLAUDE.md` imports AGENTS.md for Claude Code
|
|
13
|
+
* - `.mcp.json` the Mlola MCP server, for Claude Code and others
|
|
14
|
+
* - `.cursor/…` a rule and the MCP server, when the project uses Cursor
|
|
15
|
+
* - `.vscode/mcp.json` the MCP server, when the project uses VS Code
|
|
16
|
+
*
|
|
17
|
+
* Every write merges: anything else in these files is left as it was.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export const GUIDE_FILE = "mlola.agents.md";
|
|
21
|
+
const START = "<!-- mlola-ui:start -->";
|
|
22
|
+
const END = "<!-- mlola-ui:end -->";
|
|
23
|
+
const SERVER = { command: "npx", args: ["-y", "mlola-ui", "mcp"] };
|
|
24
|
+
|
|
25
|
+
const BRIEF = `## UI: Mlola UI
|
|
26
|
+
|
|
27
|
+
This project's interface is built with Mlola UI. Before writing or changing UI:
|
|
28
|
+
|
|
29
|
+
- Read \`${GUIDE_FILE}\` (and \`mlola-pro.agents.md\` when it exists): every
|
|
30
|
+
class, attribute and token, and the rules for new UI.
|
|
31
|
+
- Compose from Mlola components first: \`npx mlola-ui list\`,
|
|
32
|
+
\`npx mlola-ui add <name>\`. Write new CSS only for what they do not cover.
|
|
33
|
+
- Never write a color, spacing, radius, shadow or duration by hand: read the
|
|
34
|
+
\`--ml-*\` tokens. There is no Tailwind or other styling framework here.
|
|
35
|
+
- State and variants go in \`data-*\` and \`aria-*\` with the shared words
|
|
36
|
+
(\`data-tone\`, \`data-variant\`, \`data-size\`, \`data-status\`), never in extra
|
|
37
|
+
classes. \`data-theme\` and \`data-mode\` belong to the engine.
|
|
38
|
+
- The \`mlola\` MCP server (\`npx mlola-ui mcp\`) searches components, explains
|
|
39
|
+
tokens and checks markup against the contract. Check new markup with its
|
|
40
|
+
\`check_markup\` tool before finishing.`;
|
|
41
|
+
|
|
42
|
+
/** Replaces the marked section, or appends it; returns what happened. */
|
|
43
|
+
function mergeSection(filename, body) {
|
|
44
|
+
const block = `${START}\n${body}\n${END}`;
|
|
45
|
+
if (!fs.existsSync(filename)) {
|
|
46
|
+
fs.writeFileSync(filename, `${block}\n`);
|
|
47
|
+
return "created";
|
|
48
|
+
}
|
|
49
|
+
const current = fs.readFileSync(filename, "utf8");
|
|
50
|
+
const start = current.indexOf(START);
|
|
51
|
+
const end = current.indexOf(END);
|
|
52
|
+
const next = start >= 0 && end > start ? `${current.slice(0, start)}${block}${current.slice(end + END.length)}` : `${current.replace(/\s*$/, "")}\n\n${block}\n`;
|
|
53
|
+
if (next === current) return "unchanged";
|
|
54
|
+
fs.writeFileSync(filename, next);
|
|
55
|
+
return "updated";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function mergeJson(filename, update) {
|
|
59
|
+
let data = {};
|
|
60
|
+
if (fs.existsSync(filename)) {
|
|
61
|
+
try {
|
|
62
|
+
data = JSON.parse(fs.readFileSync(filename, "utf8"));
|
|
63
|
+
} catch {
|
|
64
|
+
return "skipped (not valid JSON; add the server by hand)";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const next = update(structuredClone(data));
|
|
68
|
+
if (JSON.stringify(next) === JSON.stringify(data)) return "unchanged";
|
|
69
|
+
fs.mkdirSync(path.dirname(filename), { recursive: true });
|
|
70
|
+
const existed = fs.existsSync(filename);
|
|
71
|
+
fs.writeFileSync(filename, `${JSON.stringify(next, null, 2)}\n`);
|
|
72
|
+
return existed ? "updated" : "created";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function writeAgentFiles(cwd) {
|
|
76
|
+
const results = [];
|
|
77
|
+
const record = (file, status) => results.push({ file, status });
|
|
78
|
+
|
|
79
|
+
const guide = designGuide();
|
|
80
|
+
if (guide) {
|
|
81
|
+
const filename = path.join(cwd, GUIDE_FILE);
|
|
82
|
+
const before = fs.existsSync(filename) ? fs.readFileSync(filename, "utf8") : null;
|
|
83
|
+
if (before !== guide) fs.writeFileSync(filename, guide);
|
|
84
|
+
record(GUIDE_FILE, before === null ? "created" : before === guide ? "unchanged" : "updated");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
record("AGENTS.md", mergeSection(path.join(cwd, "AGENTS.md"), BRIEF));
|
|
88
|
+
|
|
89
|
+
// Claude Code reads CLAUDE.md, which can import AGENTS.md rather than repeat it.
|
|
90
|
+
const claude = path.join(cwd, "CLAUDE.md");
|
|
91
|
+
const claudeText = fs.existsSync(claude) ? fs.readFileSync(claude, "utf8") : null;
|
|
92
|
+
if (claudeText === null) {
|
|
93
|
+
fs.writeFileSync(claude, "@AGENTS.md\n");
|
|
94
|
+
record("CLAUDE.md", "created");
|
|
95
|
+
} else if (!/^@AGENTS\.md\s*$/m.test(claudeText)) {
|
|
96
|
+
record("CLAUDE.md", mergeSection(claude, "@AGENTS.md"));
|
|
97
|
+
} else {
|
|
98
|
+
record("CLAUDE.md", "unchanged");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
record(".mcp.json", mergeJson(path.join(cwd, ".mcp.json"), (data) => ({ ...data, mcpServers: { ...(data.mcpServers ?? {}), mlola: SERVER } })));
|
|
102
|
+
|
|
103
|
+
if (fs.existsSync(path.join(cwd, ".cursor"))) {
|
|
104
|
+
record(".cursor/mcp.json", mergeJson(path.join(cwd, ".cursor", "mcp.json"), (data) => ({ ...data, mcpServers: { ...(data.mcpServers ?? {}), mlola: SERVER } })));
|
|
105
|
+
const rule = path.join(cwd, ".cursor", "rules", "mlola.mdc");
|
|
106
|
+
const text = `---\ndescription: Mlola UI, how interface code is built and styled in this project\nalwaysApply: true\n---\n\n${BRIEF.replace(/^## .*\n\n/, "")}\n`;
|
|
107
|
+
const before = fs.existsSync(rule) ? fs.readFileSync(rule, "utf8") : null;
|
|
108
|
+
if (before !== text) {
|
|
109
|
+
fs.mkdirSync(path.dirname(rule), { recursive: true });
|
|
110
|
+
fs.writeFileSync(rule, text);
|
|
111
|
+
}
|
|
112
|
+
record(".cursor/rules/mlola.mdc", before === null ? "created" : before === text ? "unchanged" : "updated");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (fs.existsSync(path.join(cwd, ".vscode"))) {
|
|
116
|
+
record(".vscode/mcp.json", mergeJson(path.join(cwd, ".vscode", "mcp.json"), (data) => ({ ...data, servers: { ...(data.servers ?? {}), mlola: { type: "stdio", ...SERVER } } })));
|
|
117
|
+
}
|
|
118
|
+
return results;
|
|
119
|
+
}
|
package/src/cli.js
CHANGED
|
@@ -7,17 +7,21 @@ import {
|
|
|
7
7
|
targetRoot,
|
|
8
8
|
writeDefaultConfig,
|
|
9
9
|
} from "./config.js";
|
|
10
|
+
import { writeAgentFiles } from "./agents.js";
|
|
10
11
|
import { addAssets, assetHint, loadAssetIndex } from "./assets.js";
|
|
11
12
|
import { runDoctor } from "./doctor.js";
|
|
12
13
|
import { collectEngineDependencies, installItems } from "./installer.js";
|
|
13
14
|
import { loadCatalogNames, loadRegistry, resolveItems } from "./registry.js";
|
|
14
15
|
import { clearCredentials, fetchProItems, GUIDE_FILENAME, hostFrom, readCredentials, saveCredentials, verifyToken, writeProGuide, writeProStyles } from "./pro.js";
|
|
16
|
+
import { serveMcp } from "./mcp.js";
|
|
15
17
|
import { pullTheme } from "./theme-pull.js";
|
|
16
18
|
|
|
17
19
|
const HELP = `Mlola UI — source-copy components with Theme
|
|
18
20
|
|
|
19
21
|
Usage:
|
|
20
|
-
mlola-ui init [--force]
|
|
22
|
+
mlola-ui init [--force] [--no-agents]
|
|
23
|
+
mlola-ui agents
|
|
24
|
+
mlola-ui mcp
|
|
21
25
|
mlola-ui add <name...> [--overwrite] [--install|--yes]
|
|
22
26
|
mlola-ui add asset <id...> [--overwrite]
|
|
23
27
|
mlola-ui login <token> [--host <url>]
|
|
@@ -27,15 +31,25 @@ Usage:
|
|
|
27
31
|
mlola-ui theme pull <theme-id | url> [--host <url>] [--overwrite]
|
|
28
32
|
|
|
29
33
|
Examples:
|
|
30
|
-
npx mlola-ui init
|
|
34
|
+
npx mlola-ui init (also tells your coding agents about Mlola)
|
|
31
35
|
npx mlola-ui add button card
|
|
32
36
|
npx mlola-ui login mlp_… (Mlola Pro: a token from /account)
|
|
33
37
|
npx mlola-ui add conversation bot
|
|
34
38
|
npx mlola-ui add asset empty-inbox orb
|
|
35
39
|
npx mlola-ui list --kind block
|
|
36
40
|
npx mlola-ui theme pull https://ui.mlola.com/t/th-4k2x9qf7wz3m
|
|
41
|
+
npx mlola-ui mcp (an MCP server for Claude Code, Cursor, Codex…)
|
|
37
42
|
`;
|
|
38
43
|
|
|
44
|
+
const CLI_VERSION = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
45
|
+
|
|
46
|
+
function reportAgents(results, output) {
|
|
47
|
+
const changed = results.filter((entry) => entry.status !== "unchanged");
|
|
48
|
+
for (const { file, status } of changed) output.log(`✓ ${status[0].toUpperCase()}${status.slice(1)} ${file}`);
|
|
49
|
+
if (!changed.length) output.log("• Agent instructions are up to date");
|
|
50
|
+
output.log("Coding agents now know this UI is Mlola: AGENTS.md points them at mlola.agents.md, and .mcp.json starts the Mlola MCP server.");
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
function hasFlag(args, ...names) {
|
|
40
54
|
return args.some((argument) => names.includes(argument));
|
|
41
55
|
}
|
|
@@ -113,6 +127,17 @@ export async function run(argv, options = {}) {
|
|
|
113
127
|
output.log(
|
|
114
128
|
`Install the engines you use, starting with: npm install ${config.engine.engine ?? "@mlola-ui/engine"} ${config.engine.motion}`,
|
|
115
129
|
);
|
|
130
|
+
if (!hasFlag(args, "--no-agents")) reportAgents(writeAgentFiles(cwd), output);
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (command === "agents") {
|
|
135
|
+
reportAgents(writeAgentFiles(cwd), output);
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (command === "mcp") {
|
|
140
|
+
await serveMcp({ cwd, run, version: CLI_VERSION });
|
|
116
141
|
return 0;
|
|
117
142
|
}
|
|
118
143
|
|