@parity-app/cli 0.4.0 → 0.5.1
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/dist/bin.mjs +255 -34
- package/dist/{client-Cf66-n3R.mjs → client-CoW-KcnT.mjs} +130 -141
- package/dist/index.d.mts +98 -7
- package/dist/index.mjs +1 -1
- package/dist/schema-BpGSCLEu.mjs +113 -0
- package/dist/{src-y3hdgbK2.mjs → src-5CrSA_RX.mjs} +1 -1
- package/dist/{src-CYEKdXm_.mjs → src-C4faIpux.mjs} +142 -3
- package/dist/{src-CJUvccJO.mjs → src-Cr8pfFJE.mjs} +1 -1
- package/dist/{src-DaCYZuwb.mjs → src-Zm_PYFFH.mjs} +10 -5
- package/dist/src-p0vFxRBz.mjs +3 -0
- package/package.json +3 -2
- package/skills/SKILL.md +3 -2
- package/skills/execute.md +136 -7
- package/skills/guide/checking.md +6 -3
- package/skills/guide/components.md +3 -1
- package/skills/guide/states-and-modes.md +14 -0
- package/dist/src-DgI96EpD.mjs +0 -3
package/dist/bin.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { a as errorCodes, i as closest, o as errorDetails, r as CodedError, s as readErrorDetails } from "./schema-BpGSCLEu.mjs";
|
|
3
|
+
import { a as describeExec, c as describeProps, f as setCaller, i as describeConsole, l as describeStatus, n as describeAccessibility, o as describeModes, p as mcpCallerName, r as describeComponents, s as describeProblems, t as call, u as describeTokens } from "./client-CoW-KcnT.mjs";
|
|
3
4
|
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
4
5
|
import { dirname, join, normalize, relative, resolve, sep } from "node:path";
|
|
5
6
|
import { parseArgs } from "node:util";
|
|
@@ -99,6 +100,120 @@ function structuredExec(result) {
|
|
|
99
100
|
screenshots: result.screenshots.map(({ png: _png, ...shot }) => shot)
|
|
100
101
|
};
|
|
101
102
|
}
|
|
103
|
+
const screenshotSchema = {
|
|
104
|
+
type: "object",
|
|
105
|
+
properties: {
|
|
106
|
+
path: {
|
|
107
|
+
type: "string",
|
|
108
|
+
description: "Where the PNG was saved."
|
|
109
|
+
},
|
|
110
|
+
design: { type: "string" },
|
|
111
|
+
state: { type: "string" },
|
|
112
|
+
mode: { type: "string" }
|
|
113
|
+
},
|
|
114
|
+
required: [
|
|
115
|
+
"path",
|
|
116
|
+
"design",
|
|
117
|
+
"state",
|
|
118
|
+
"mode"
|
|
119
|
+
]
|
|
120
|
+
};
|
|
121
|
+
const strings$1 = {
|
|
122
|
+
type: "array",
|
|
123
|
+
items: { type: "string" }
|
|
124
|
+
};
|
|
125
|
+
const discardedSchema = {
|
|
126
|
+
type: "array",
|
|
127
|
+
description: "Patches each Replace threw away with the node it swapped out. Present only when there were some; reapply what's still wanted to the replacement with Responsive, Update with a state, or UpdateState.",
|
|
128
|
+
items: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {
|
|
131
|
+
design: { type: "string" },
|
|
132
|
+
replaced: {
|
|
133
|
+
type: "string",
|
|
134
|
+
description: "The node Replace swapped out."
|
|
135
|
+
},
|
|
136
|
+
replacement: {
|
|
137
|
+
type: "string",
|
|
138
|
+
description: "The node that took its place."
|
|
139
|
+
},
|
|
140
|
+
nodes: {
|
|
141
|
+
type: "array",
|
|
142
|
+
items: {
|
|
143
|
+
type: "object",
|
|
144
|
+
properties: {
|
|
145
|
+
id: {
|
|
146
|
+
type: "string",
|
|
147
|
+
description: "The old node's id, or instance/inner path."
|
|
148
|
+
},
|
|
149
|
+
name: { type: "string" },
|
|
150
|
+
viewports: {
|
|
151
|
+
...strings$1,
|
|
152
|
+
description: "Viewport ids it had responsive patches for."
|
|
153
|
+
},
|
|
154
|
+
states: {
|
|
155
|
+
...strings$1,
|
|
156
|
+
description: "State ids it had patches in."
|
|
157
|
+
},
|
|
158
|
+
variants: {
|
|
159
|
+
...strings$1,
|
|
160
|
+
description: "Variant options it had patches in, as param=option."
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
required: ["id"]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
required: [
|
|
168
|
+
"design",
|
|
169
|
+
"replaced",
|
|
170
|
+
"replacement",
|
|
171
|
+
"nodes"
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const warningGroupsSchema = {
|
|
176
|
+
type: "array",
|
|
177
|
+
description: "The warnings as data, in the same order: each finding once, with how many places and which. Errors come first, then warnings, then suggestions.",
|
|
178
|
+
items: {
|
|
179
|
+
type: "object",
|
|
180
|
+
properties: {
|
|
181
|
+
category: {
|
|
182
|
+
type: "string",
|
|
183
|
+
description: "Stable: render_failed, unknown_component, unknown_component_design, unknown_prop, invalid_option, not_a_token, not_a_length_token, overlap, kind_changed or unnamed_layout."
|
|
184
|
+
},
|
|
185
|
+
severity: {
|
|
186
|
+
type: "string",
|
|
187
|
+
enum: [
|
|
188
|
+
"error",
|
|
189
|
+
"warning",
|
|
190
|
+
"suggestion"
|
|
191
|
+
],
|
|
192
|
+
description: "error: a render failed, so a check or screenshot is missing. suggestion: worth doing, not wrong."
|
|
193
|
+
},
|
|
194
|
+
message: {
|
|
195
|
+
type: "string",
|
|
196
|
+
description: "What's wrong and what to do about it."
|
|
197
|
+
},
|
|
198
|
+
count: {
|
|
199
|
+
type: "integer",
|
|
200
|
+
minimum: 1,
|
|
201
|
+
description: "How many places it was found."
|
|
202
|
+
},
|
|
203
|
+
at: {
|
|
204
|
+
...strings$1,
|
|
205
|
+
description: "Every place: a node's design/node path, or a frame. Empty for a whole board."
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
required: [
|
|
209
|
+
"category",
|
|
210
|
+
"severity",
|
|
211
|
+
"message",
|
|
212
|
+
"count",
|
|
213
|
+
"at"
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
};
|
|
102
217
|
/** Execute's and screenshot's structured result. */
|
|
103
218
|
const execOutputSchema = {
|
|
104
219
|
type: "object",
|
|
@@ -114,34 +229,19 @@ const execOutputSchema = {
|
|
|
114
229
|
description: "Lines from Print."
|
|
115
230
|
},
|
|
116
231
|
warnings: {
|
|
117
|
-
|
|
118
|
-
|
|
232
|
+
...strings$1,
|
|
233
|
+
description: "One line per warning group, places first."
|
|
119
234
|
},
|
|
235
|
+
warningGroups: warningGroupsSchema,
|
|
120
236
|
created: {
|
|
121
237
|
type: "object",
|
|
122
238
|
additionalProperties: { type: "string" },
|
|
123
239
|
description: "Names of designs and nodes created, mapped to their ids."
|
|
124
240
|
},
|
|
241
|
+
discarded: discardedSchema,
|
|
125
242
|
screenshots: {
|
|
126
243
|
type: "array",
|
|
127
|
-
items:
|
|
128
|
-
type: "object",
|
|
129
|
-
properties: {
|
|
130
|
-
path: {
|
|
131
|
-
type: "string",
|
|
132
|
-
description: "Where the PNG was saved."
|
|
133
|
-
},
|
|
134
|
-
design: { type: "string" },
|
|
135
|
-
state: { type: "string" },
|
|
136
|
-
mode: { type: "string" }
|
|
137
|
-
},
|
|
138
|
-
required: [
|
|
139
|
-
"path",
|
|
140
|
-
"design",
|
|
141
|
-
"state",
|
|
142
|
-
"mode"
|
|
143
|
-
]
|
|
144
|
-
}
|
|
244
|
+
items: screenshotSchema
|
|
145
245
|
},
|
|
146
246
|
error: operationErrorSchema
|
|
147
247
|
},
|
|
@@ -287,8 +387,8 @@ const executeOperation = {
|
|
|
287
387
|
*/
|
|
288
388
|
async function runCheck(library, options) {
|
|
289
389
|
if (!library) throw new Error("parity lib check <library> [--tab t] [--mode m]");
|
|
290
|
-
const { applyLibraryEdits, componentNode, generateId, librarySource, parseLibraryEdits, withLibraryContext } = await import("./src-
|
|
291
|
-
const { registryDir, registryEntries } = await import("./src-
|
|
390
|
+
const { applyLibraryEdits, componentNode, generateId, librarySource, parseLibraryEdits, withLibraryContext } = await import("./src-p0vFxRBz.mjs");
|
|
391
|
+
const { registryDir, registryEntries } = await import("./src-Cr8pfFJE.mjs");
|
|
292
392
|
const entry = (await registryEntries()).find((item) => item.manifest.id === library);
|
|
293
393
|
if (!entry) throw new Error(`The registry has no library "${library}"`);
|
|
294
394
|
let manifest = entry.manifest;
|
|
@@ -416,8 +516,8 @@ function describeCheck(report) {
|
|
|
416
516
|
* because it reads the project's files and its own copy of TypeScript.
|
|
417
517
|
*/
|
|
418
518
|
async function runLib(packageName, options) {
|
|
419
|
-
const { appManifestPath, generateLibrary, manifestText, mergeManifest, reviseLibrary } = await import("./src-
|
|
420
|
-
const { covers, registryDir, registryEntries } = await import("./src-
|
|
519
|
+
const { appManifestPath, generateLibrary, manifestText, mergeManifest, reviseLibrary } = await import("./src-Zm_PYFFH.mjs");
|
|
520
|
+
const { covers, registryDir, registryEntries } = await import("./src-Cr8pfFJE.mjs");
|
|
421
521
|
const spec = packageName === void 0 ? void 0 : packageSpec(packageName);
|
|
422
522
|
let root = resolve(options.root ?? ".");
|
|
423
523
|
if (spec && (spec.version !== void 0 || options.registry && !options.root)) {
|
|
@@ -428,7 +528,7 @@ async function runLib(packageName, options) {
|
|
|
428
528
|
console.error(`Installing ${spec.name} ${version} on its own…`);
|
|
429
529
|
root = await installedVersion(spec.name, version);
|
|
430
530
|
}
|
|
431
|
-
const { parseLibraryEdits } = await import("./src-
|
|
531
|
+
const { parseLibraryEdits } = await import("./src-Zm_PYFFH.mjs");
|
|
432
532
|
const trialEdits = options.edits ? parseLibraryEdits(JSON.parse(await readFile(resolve(options.edits), "utf8"))) : void 0;
|
|
433
533
|
const recordedId = options.registry && spec ? options.id ?? (await registryEntries()).find((entry) => entry.manifest.package?.name === spec.name)?.manifest.id : void 0;
|
|
434
534
|
const appErrors = recordedId ? await readAppErrors(registryDir(), recordedId) : void 0;
|
|
@@ -778,6 +878,13 @@ const frameSchema = {
|
|
|
778
878
|
state: string,
|
|
779
879
|
mode: string
|
|
780
880
|
};
|
|
881
|
+
const number = { type: "number" };
|
|
882
|
+
const boxSchema = object({
|
|
883
|
+
x: number,
|
|
884
|
+
y: number,
|
|
885
|
+
width: number,
|
|
886
|
+
height: number
|
|
887
|
+
});
|
|
781
888
|
const designSchema = object({
|
|
782
889
|
id: string,
|
|
783
890
|
name: string,
|
|
@@ -899,9 +1006,44 @@ const problemsSchema = object({
|
|
|
899
1006
|
type: "array",
|
|
900
1007
|
items: object({
|
|
901
1008
|
...frameSchema,
|
|
1009
|
+
kind: {
|
|
1010
|
+
type: "string",
|
|
1011
|
+
enum: [
|
|
1012
|
+
"render-error",
|
|
1013
|
+
"unknown-component",
|
|
1014
|
+
"content-wider",
|
|
1015
|
+
"frame-overflow",
|
|
1016
|
+
"clipped"
|
|
1017
|
+
]
|
|
1018
|
+
},
|
|
902
1019
|
problem: string,
|
|
903
|
-
node: string
|
|
904
|
-
|
|
1020
|
+
node: string,
|
|
1021
|
+
name: string,
|
|
1022
|
+
box: boxSchema,
|
|
1023
|
+
container: object({
|
|
1024
|
+
node: string,
|
|
1025
|
+
name: string,
|
|
1026
|
+
box: boxSchema
|
|
1027
|
+
}, ["node", "name"]),
|
|
1028
|
+
overflow: object({
|
|
1029
|
+
left: number,
|
|
1030
|
+
right: number,
|
|
1031
|
+
top: number,
|
|
1032
|
+
bottom: number
|
|
1033
|
+
}, [
|
|
1034
|
+
"left",
|
|
1035
|
+
"right",
|
|
1036
|
+
"top",
|
|
1037
|
+
"bottom"
|
|
1038
|
+
])
|
|
1039
|
+
}, [
|
|
1040
|
+
"kind",
|
|
1041
|
+
"node",
|
|
1042
|
+
"name",
|
|
1043
|
+
"box",
|
|
1044
|
+
"container",
|
|
1045
|
+
"overflow"
|
|
1046
|
+
])
|
|
905
1047
|
},
|
|
906
1048
|
frames: integer,
|
|
907
1049
|
warnings: strings
|
|
@@ -1002,8 +1144,86 @@ const propsSchema = object({
|
|
|
1002
1144
|
"default",
|
|
1003
1145
|
"required"
|
|
1004
1146
|
])
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1147
|
+
},
|
|
1148
|
+
composition: object({
|
|
1149
|
+
role: {
|
|
1150
|
+
type: "string",
|
|
1151
|
+
enum: [
|
|
1152
|
+
"provider",
|
|
1153
|
+
"wrapper",
|
|
1154
|
+
"component"
|
|
1155
|
+
],
|
|
1156
|
+
description: "provider draws nothing and gives parts inside it context; wrapper draws and holds other parts."
|
|
1157
|
+
},
|
|
1158
|
+
parents: object({
|
|
1159
|
+
status: {
|
|
1160
|
+
type: "string",
|
|
1161
|
+
enum: [
|
|
1162
|
+
"listed",
|
|
1163
|
+
"none",
|
|
1164
|
+
"unknown"
|
|
1165
|
+
],
|
|
1166
|
+
description: "listed: insert it inside chain; none: it needs nothing; unknown: nothing says, see reason."
|
|
1167
|
+
},
|
|
1168
|
+
chain: {
|
|
1169
|
+
type: "array",
|
|
1170
|
+
description: "Outermost first.",
|
|
1171
|
+
items: object({
|
|
1172
|
+
component: string,
|
|
1173
|
+
optional: boolean_
|
|
1174
|
+
}, ["optional"])
|
|
1175
|
+
},
|
|
1176
|
+
from: {
|
|
1177
|
+
...string,
|
|
1178
|
+
description: "What said so, such as the library's examples or the error it throws."
|
|
1179
|
+
},
|
|
1180
|
+
reason: string
|
|
1181
|
+
}, [
|
|
1182
|
+
"chain",
|
|
1183
|
+
"from",
|
|
1184
|
+
"reason"
|
|
1185
|
+
]),
|
|
1186
|
+
holds: {
|
|
1187
|
+
...strings,
|
|
1188
|
+
description: "Parts that go directly inside it."
|
|
1189
|
+
},
|
|
1190
|
+
slots: {
|
|
1191
|
+
type: "array",
|
|
1192
|
+
items: object({
|
|
1193
|
+
name: string,
|
|
1194
|
+
key: string,
|
|
1195
|
+
kind: {
|
|
1196
|
+
type: "string",
|
|
1197
|
+
enum: [
|
|
1198
|
+
"children",
|
|
1199
|
+
"element",
|
|
1200
|
+
"render"
|
|
1201
|
+
]
|
|
1202
|
+
}
|
|
1203
|
+
})
|
|
1204
|
+
},
|
|
1205
|
+
example: object({
|
|
1206
|
+
node: {
|
|
1207
|
+
type: "object",
|
|
1208
|
+
description: "A node Insert takes as it is: the component inside its parents."
|
|
1209
|
+
},
|
|
1210
|
+
status: {
|
|
1211
|
+
type: "string",
|
|
1212
|
+
enum: [
|
|
1213
|
+
"drawn",
|
|
1214
|
+
"failing",
|
|
1215
|
+
"untried"
|
|
1216
|
+
],
|
|
1217
|
+
description: "Whether the component has drawn on the canvas."
|
|
1218
|
+
},
|
|
1219
|
+
reason: string
|
|
1220
|
+
}, ["reason"])
|
|
1221
|
+
})
|
|
1222
|
+
}, [
|
|
1223
|
+
"path",
|
|
1224
|
+
"import",
|
|
1225
|
+
"composition"
|
|
1226
|
+
]);
|
|
1007
1227
|
const viewportSchema = object({
|
|
1008
1228
|
id: string,
|
|
1009
1229
|
name: string,
|
|
@@ -1334,13 +1554,13 @@ const tools = [
|
|
|
1334
1554
|
}
|
|
1335
1555
|
},
|
|
1336
1556
|
operationTool("screenshot", "Capture a design in any of its states and modes, rendered offscreen at real widths. state and mode take an id, a list, or \"all\"; mode also takes \"shown\".", operations.screenshot, (result) => [text(describeExec(result)), ...result.screenshots.map((shot) => image(shot.png))]),
|
|
1337
|
-
operationTool("find_problems", "Find layout problems in a design, rendered offscreen in every state and the modes it shows unless you narrow it: render errors,
|
|
1338
|
-
operationTool("check_accessibility", "Check a design's accessibility with axe-core against WCAG 2.2 AA, rendered offscreen in every state and the modes it shows unless you narrow it. Lists each rule broken, worst first, with the layers that break it (ids you can pass to execute), the frames, what's wrong and a link on how to fix it. state and mode take an id, a list, or \"all\"; mode also takes \"shown\". Automated checks find some issues, not all.", operations.accessibility, (result) => [text(describeAccessibility(result))]),
|
|
1557
|
+
operationTool("find_problems", "Find layout problems in a design, rendered offscreen in every state and the modes it shows unless you narrow it: render errors, nodes that stick out of the frame, nodes cut off by an ancestor that clips, and components that aren't the project's. Each layout finding names the node and what it overflows, with both boxes and how far past each edge. Run it after changes, with screenshot. state and mode take an id, a list, or \"all\"; mode also takes \"shown\".", operations.problems, (result) => [text(describeProblems(result))]),
|
|
1558
|
+
operationTool("check_accessibility", "Check a design's accessibility with axe-core against WCAG 2.2 AA, rendered offscreen in every state and the modes it shows unless you narrow it. Lists each rule broken, worst first, with the layers that break it (ids you can pass to execute), the frames, what's wrong and a link on how to fix it. A contrast failure names the color token to set as style.foreground so it passes in every frame checked, when one does. state and mode take an id, a list, or \"all\"; mode also takes \"shown\". Automated checks find some issues, not all.", operations.accessibility, (result) => [text(describeAccessibility(result))]),
|
|
1339
1559
|
operationTool("get_console", "Read what the project's own code wrote to the console: errors, warnings and logs from its components on the canvas, including while the person interacts with them, and from offscreen renders such as screenshots. Oldest first; the same message several times in a row is counted once. clear: true empties it after reading, so the next read shows only what's new.", operations.console, (result) => [text(describeConsole(result))]),
|
|
1340
1560
|
operationTool("open_project", "Open a project folder in a new Parity tab, or switch to it if it's already open.", operations.open, json),
|
|
1341
1561
|
operationTool("get_tokens", "Read tokens filtered by category, source or name, with values in every theme.", operations.tokens, (result) => [text(describeTokens(result))]),
|
|
1342
1562
|
operationTool("get_components", "List project components, libraries, icon sets and exports that were left out or failed to render.", operations.components, (result) => [text(describeComponents(result))]),
|
|
1343
|
-
operationTool("get_props", "Read a component's props from source. all includes attributes it passes through.", operations.props, (result) => [text(describeProps(result))]),
|
|
1563
|
+
operationTool("get_props", "Read a component's props from source, and its composition: the parents or provider it goes inside, the parts it holds, its slots and an example node to insert. all includes attributes it passes through.", operations.props, (result) => [text(describeProps(result))]),
|
|
1344
1564
|
{
|
|
1345
1565
|
name: "read_skill",
|
|
1346
1566
|
description: "Read the Parity design skill or a file it references.",
|
|
@@ -1465,7 +1685,8 @@ const usage = `parity: drive the Parity app from a terminal or an agent
|
|
|
1465
1685
|
unless --limit says
|
|
1466
1686
|
parity components [--tab t] the components designs can use, by library
|
|
1467
1687
|
parity props <Component> [--all] [--tab t]
|
|
1468
|
-
a component's props from its source
|
|
1688
|
+
a component's props from its source, then what it goes inside and holds,
|
|
1689
|
+
with an example to insert; --all adds the attributes it passes on
|
|
1469
1690
|
parity lib [package] [--root dir] [--out file|-] [--registry] [--id id] [--name n] [--range r] [--json]
|
|
1470
1691
|
[--only new|all|A,B] [--edits file] [--no-examples] [--no-tags]
|
|
1471
1692
|
write a .lib.par: a package's components, tokens, breakpoints, icons and
|