@elyx-design/cli 0.0.1-preview.14303.24b991c07 → 0.0.1-preview.14918.b8a492b89

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.
Files changed (2) hide show
  1. package/README.md +140 -0
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -9,6 +9,14 @@ npm install --global @elyx-design/cli
9
9
  elyx --help
10
10
  ```
11
11
 
12
+ Open a project folder in the matching Elyx app release (development, nightly,
13
+ preview, or public):
14
+
15
+ ```sh
16
+ elyx .
17
+ elyx /path/to/project
18
+ ```
19
+
12
20
  This package provides the JavaScript launcher. The native executable is
13
21
  installed through an optional package selected for the current operating system
14
22
  and architecture.
@@ -43,3 +51,135 @@ native executable.
43
51
 
44
52
  The daemon also compiles rendering, inspection, lint, and scene code from
45
53
  `src/`. Mosaic uses its native font-loading code.
54
+
55
+ The Figma reader and its CLI adapter live in `src/fig/`. Its miniz
56
+ and Zstandard dependencies are also listed in `cpp-vendors.yml` and are only
57
+ configured by the native CLI build. The daemon also builds the reader and
58
+ converter using its own pinned dependencies for sidebar `.fig` imports.
59
+ Both native targets use libcurl for Google Fonts downloads (on Linux, install
60
+ `libcurl4-openssl-dev` to build; macOS provides libcurl in its SDK).
61
+
62
+ ## Building an Elyx model
63
+
64
+ For `.fig` decoding and the `elyx fig inspect` and `elyx fig convert` commands,
65
+ see [the Figma reader and converter](src/fig/README.md).
66
+
67
+ `ElyxLang::ElyxModelBuilder` builds objects from `Model.h` without creating an
68
+ `MSWorld`. It uses `elyxSchema()` to find fields, check units, select the existing
69
+ value codec, and order properties. `build()` transfers the declarations into a
70
+ `ModelValue` containing a `ModelBoard`.
71
+
72
+ Pass an `ElyxModelBuilder::Layer` tree to `addLayer()`. Children keep their input
73
+ order and are declared inside their parent, alongside the `children:` references.
74
+ Names must be unique among siblings; separate parents can reuse a child name.
75
+ The schema determines which layer types accept children.
76
+
77
+ Properties currently support literal lengths, such as frame width and height,
78
+ and a single solid `fill` supplied as an `MSColor`. Color channels, including
79
+ alpha, must be finite values between 0 and 1. The builder validates the fill
80
+ through the schema's shorthand expansion, paint branch, and color codec, then
81
+ keeps the typed color for formatting. Paint lists and paint objects are not yet
82
+ supported.
83
+
84
+ Unknown properties, invalid or duplicate symbols, invalid lengths, unsupported
85
+ property structures, and nesting beyond 512 child levels return an error. A
86
+ failed `addLayer()` leaves the entire document unchanged, even when the error is
87
+ in a descendant. Accepted values are copied; the builder does not omit defaults.
88
+
89
+ The model carries a distinct namespace for each layer's declarations. The
90
+ formatter uses those namespaces to render local child references without an
91
+ external namespace resolver.
92
+
93
+ The schema must outlive the builder. The process-wide `elyxSchema()` does.
94
+
95
+ ## Create a frame with colored children and write it to disk
96
+
97
+ ```cpp
98
+ #include <fstream>
99
+ #include <stdexcept>
100
+ #include <utility>
101
+
102
+ #include "ElyxLang/ElyxFormatter.h"
103
+ #include "ElyxLang/ElyxModelBuilder.h"
104
+ #include "ElyxLang/ElyxSchema.h"
105
+ #include "primitives/MSColor.h"
106
+
107
+ int main() {
108
+ using namespace ElyxLang;
109
+
110
+ ElyxModelBuilder document{Schema::elyxSchema()};
111
+ ElyxModelBuilder::Layer card{
112
+ .kind = ModelBuiltinBase::Frame,
113
+ .name = "card",
114
+ };
115
+ card.properties.add("width", ModelValue{ast::Length::Pixel(320)});
116
+ card.properties.add("height", ModelValue{ast::Length::Pixel(200)});
117
+ card.properties.add("fill", ModelValue{MSColor::White()});
118
+
119
+ ElyxModelBuilder::Layer rectangle{
120
+ .kind = ModelBuiltinBase::Frame,
121
+ .name = "rectangle",
122
+ };
123
+ rectangle.properties.add("left", ModelValue{ast::Length::Pixel(16)});
124
+ rectangle.properties.add("top", ModelValue{ast::Length::Pixel(24)});
125
+ rectangle.properties.add("width", ModelValue{ast::Length::Pixel(80)});
126
+ rectangle.properties.add("height", ModelValue{ast::Length::Pixel(40)});
127
+ rectangle.properties.add("fill", ModelValue{MSColor::Red()});
128
+ card.children.push_back(std::move(rectangle));
129
+
130
+ ElyxModelBuilder::Layer translucent{
131
+ .kind = ModelBuiltinBase::Frame,
132
+ .name = "translucent",
133
+ };
134
+ translucent.properties.add("left", ModelValue{ast::Length::Pixel(128)});
135
+ translucent.properties.add("top", ModelValue{ast::Length::Pixel(24)});
136
+ translucent.properties.add("width", ModelValue{ast::Length::Pixel(80)});
137
+ translucent.properties.add("height", ModelValue{ast::Length::Pixel(40)});
138
+ translucent.properties.add("fill", ModelValue{MSColor::Blue().withAlpha(0.5F)});
139
+ card.children.push_back(std::move(translucent));
140
+
141
+ if (auto result = document.addLayer(card); !result) {
142
+ throw std::runtime_error(result.error());
143
+ }
144
+ auto model = std::move(document).build();
145
+
146
+ pp::DocumentBuilder output;
147
+ pp::PrettyPrinter printer;
148
+ pp::DefaultLayout layout;
149
+ const auto &formatted = printer.pp(output, model);
150
+
151
+ std::ofstream file;
152
+ file.exceptions(std::ios::failbit | std::ios::badbit);
153
+ file.open("card.elyx");
154
+ file << printer.render(formatted, layout);
155
+ file.close();
156
+ }
157
+ ```
158
+
159
+ Additional paint types and references to other scopes are later steps. The Figma
160
+ converter calls this shared language API; the CLI handles arguments and output
161
+ files.
162
+
163
+ ## Layer targets
164
+
165
+ Inspection returns a `target` on component nodes and bounds, hit, and rectangle
166
+ results. It contains `filePath`, `sourceRef`, and `overridePath`; a null target
167
+ means the runtime layer has no reusable source address. Other fields such as
168
+ `symbol`, `ref`, and `path` describe the layer, rather than identifying an exact
169
+ instance occurrence.
170
+
171
+ Use the target's file path as the CLI input, `sourceRef` as inspect's `--ref` or
172
+ render's `--symbol`, and `overridePath` as `--override-path`. For example:
173
+
174
+ ```sh
175
+ elyx inspect component screen.elyx --ref=musicPlayer.track.save
176
+ elyx inspect bounds screen.elyx --ref=card --override-path="'ui.Body.Label"
177
+ elyx render screen.elyx --symbol=card --override-path="'ui.Body.Label" -o label.png
178
+ ```
179
+
180
+ Copy override paths from inspection; their namespace qualifiers distinguish
181
+ imported descendants. Ambiguous source references fail instead of choosing an
182
+ instance. In MCP, pass the returned object as `query.target` to inspect
183
+ bounds/component, `target` to render, or an entry in focus's `targets` array.
184
+ Spatial inspect queries use `query.filePath`. To render a whole document, pass
185
+ `target: {filePath: "screen.elyx"}`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elyx-design/cli",
3
- "version": "0.0.1-preview.14303.24b991c07",
3
+ "version": "0.0.1-preview.14918.b8a492b89",
4
4
  "description": "Command-line tools for Elyx",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {
@@ -22,7 +22,7 @@
22
22
  "dist"
23
23
  ],
24
24
  "optionalDependencies": {
25
- "@elyx-design/cli-darwin-arm64": "0.0.1-preview.14303.24b991c07",
26
- "@elyx-design/cli-linux-x64": "0.0.1-preview.14303.24b991c07"
25
+ "@elyx-design/cli-darwin-arm64": "0.0.1-preview.14918.b8a492b89",
26
+ "@elyx-design/cli-linux-x64": "0.0.1-preview.14918.b8a492b89"
27
27
  }
28
28
  }