figma-cache-toolchain 2.0.4 → 2.0.5
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 +1 -5
- package/figma-cache/docs/README.md +4 -3
- package/package.json +1 -1
- package/scripts/cross-project-e2e.js +144 -3
- package/scripts/ui-1to1-audit.js +1 -1
- package/scripts/ui-auto-acceptance.js +3 -3
- package/scripts/ui-preflight.js +1 -1
- package/scripts/ui-report-aggregate.js +3 -3
package/README.md
CHANGED
|
@@ -125,7 +125,6 @@ npm run figma:ui:preflight
|
|
|
125
125
|
npm run figma:ui:audit -- --min-score=85
|
|
126
126
|
npm run figma:ui:report:aggregate
|
|
127
127
|
npm run figma:ui:accept -- --target=src/components/YourComponent.tsx
|
|
128
|
-
npm run figma:ui:e2e:cross -- --target-project=E:/Work/vue-demo --fileKey=<fileKey> --nodeId=9277-28772 --target=E:/Work/vue-demo/src/components/YourComponent.vue
|
|
129
128
|
npm run figma:ui:gate
|
|
130
129
|
npm run figma:ui:gate:pr
|
|
131
130
|
npm run figma:ui:gate:main
|
|
@@ -144,11 +143,8 @@ UI preflight/gate 说明:
|
|
|
144
143
|
- `figma:ui:gate` 会先跑 preflight + audit(默认阈值 `85`),再串联 `validate`、`cursor:shadow:check` 与 `npm test`
|
|
145
144
|
- `figma:ui:report:aggregate` 会聚合 preflight + audit 报告,输出 `figma-cache/reports/ui-quality-summary.json`
|
|
146
145
|
- `figma:ui:accept` 是一键自动验收:自动跑 preflight + audit + aggregate,并按效果阈值直接返回 pass/fail(退出码)
|
|
147
|
-
- `figma:ui:e2e:cross` 是跨项目联调:自动 `npm pack` 当前包 -> 安装到目标项目 -> 执行自动验收 -> 回收报告路径与摘要
|
|
148
|
-
- 支持 `--auto-ensure-on-miss`:cache miss 时自动尝试 `--source=figma-mcp ensure`
|
|
149
|
-
- 支持 `--batch-file=<json>`:批量节点联调并汇总结果(单条失败即整体失败)
|
|
150
|
-
- 支持 `--fix-loop=<N>`:失败后自动执行自修复重试(补 contract / 刷新缓存后重跑)
|
|
151
146
|
- CI 建议矩阵:`figma:ui:gate:pr`(PR 最低门槛)与 `figma:ui:gate:main`(主干严格门槛)
|
|
147
|
+
- `figma:ui:e2e:cross` 现默认启用“真实组件链路保护”:`--target` 不存在或验收出现 `code-level comparison skipped` 会直接失败,避免“未绑定真实组件但通过”的假阳性;如需兼容历史流程可显式传 `--allow-skipped-code-level-comparison`
|
|
152
148
|
|
|
153
149
|
UI profile 分层(P3):
|
|
154
150
|
|
|
@@ -83,7 +83,7 @@ npm run figma:cache:config
|
|
|
83
83
|
|
|
84
84
|
### UI preflight(P0 门禁)
|
|
85
85
|
|
|
86
|
-
- `npm run figma:ui:preflight`:读取 `index.json`、adapter contract 与节点关键文件,输出结构化报告到 `figma-cache/reports/ui-preflight-report.json`
|
|
86
|
+
- `npm run figma:ui:preflight`:读取 `index.json`、adapter contract 与节点关键文件,输出结构化报告到 `figma-cache/reports/runtime/ui-preflight-report.json`
|
|
87
87
|
- 支持参数:`--cacheKey=<fileKey#nodeId>`、`--contract=<path>`、`--report=<path>`、`--allow-warn`
|
|
88
88
|
- 阻断项返回退出码 `2`:包括 cacheKey 不存在、关键文件缺失、coverage evidence 不完整、contract 缺失或映射为空、`source=figma-mcp` 时缺失 `mcp-raw-manifest.json`
|
|
89
89
|
- warning 项(不阻断)会提示 `spec.md`/`state-map.md` 中的 TODO 占位
|
|
@@ -97,7 +97,7 @@ npm run figma:cache:config
|
|
|
97
97
|
### UI 1:1 audit(P1 质量评分)
|
|
98
98
|
|
|
99
99
|
- `npm run figma:ui:audit -- --cacheKey=<fileKey#nodeId> --target=<componentPath> --min-score=85`
|
|
100
|
-
- 默认报告:`figma-cache/reports/ui-1to1-report.json`
|
|
100
|
+
- 默认报告:`figma-cache/reports/runtime/ui-1to1-report.json`
|
|
101
101
|
- 报告结构遵循:`figma-cache/docs/ui-1to1-report.schema.json`
|
|
102
102
|
- 评分字段:`score.total/layout/text/token/state/interaction`
|
|
103
103
|
- `score.total` 低于 `--min-score` 会返回退出码 `2`(可用于 CI 门禁)
|
|
@@ -128,7 +128,7 @@ npm run figma:cache:config
|
|
|
128
128
|
- `standard`:audit 默认阈值 85
|
|
129
129
|
- `strict`:preflight warning 计入阻断、audit 默认阈值 92 且要求 `--target`
|
|
130
130
|
- 报告聚合:`npm run figma:ui:report:aggregate`
|
|
131
|
-
- 输出:`figma-cache/reports/ui-quality-summary.json`
|
|
131
|
+
- 输出:`figma-cache/reports/runtime/ui-quality-summary.json`
|
|
132
132
|
|
|
133
133
|
### 一键自动验收(效果导向)
|
|
134
134
|
|
|
@@ -157,6 +157,7 @@ npm run figma:cache:config
|
|
|
157
157
|
- `--allow-skeleton-with-figma-mcp`:允许 skeleton 写入(仅建议应急)
|
|
158
158
|
- `--batch-file=<json>`:批量执行,多节点一次联调
|
|
159
159
|
- `--fix-loop=<N>`:失败自动重试 N 轮(重试前会补 contract 并刷新缓存)
|
|
160
|
+
- `--emit-agent-task-on-fail`:失败自动产出 `agent-task.md`,用于交给 Cursor Agent 接力修复
|
|
160
161
|
|
|
161
162
|
### 严格 validate 规则(默认)
|
|
162
163
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figma-cache-toolchain",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "Figma link normalization, local cache index, validation, and Node CLI (framework-agnostic core).",
|
|
5
5
|
"homepage": "https://github.com/907086379/figma-cache-toolchain#readme",
|
|
6
6
|
"keywords": [
|
|
@@ -34,6 +34,9 @@ function parseArgs(argv) {
|
|
|
34
34
|
completeness: "layout,text,tokens,interactions,states,accessibility",
|
|
35
35
|
batchFile: "",
|
|
36
36
|
fixLoop: 0,
|
|
37
|
+
emitAgentTaskOnFail: false,
|
|
38
|
+
agentTaskPath: "",
|
|
39
|
+
allowSkippedCodeLevelComparison: false,
|
|
37
40
|
};
|
|
38
41
|
|
|
39
42
|
argv.forEach((arg) => {
|
|
@@ -103,6 +106,18 @@ function parseArgs(argv) {
|
|
|
103
106
|
if (arg.startsWith("--fix-loop=")) {
|
|
104
107
|
const n = Number(arg.split("=").slice(1).join("=").trim());
|
|
105
108
|
options.fixLoop = Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (arg === "--emit-agent-task-on-fail") {
|
|
112
|
+
options.emitAgentTaskOnFail = true;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (arg.startsWith("--agent-task-path=")) {
|
|
116
|
+
options.agentTaskPath = arg.split("=").slice(1).join("=").trim();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (arg === "--allow-skipped-code-level-comparison") {
|
|
120
|
+
options.allowSkippedCodeLevelComparison = true;
|
|
106
121
|
}
|
|
107
122
|
});
|
|
108
123
|
|
|
@@ -164,6 +179,63 @@ function normalizeSlash(input) {
|
|
|
164
179
|
return String(input || "").replace(/\\/g, "/");
|
|
165
180
|
}
|
|
166
181
|
|
|
182
|
+
function writeAgentTask(targetProject, options, payload) {
|
|
183
|
+
const defaultPath = path.join(targetProject, "agent-task.md");
|
|
184
|
+
const taskPath = options.agentTaskPath
|
|
185
|
+
? resolveMaybeAbsolutePath(options.agentTaskPath)
|
|
186
|
+
: defaultPath;
|
|
187
|
+
const lines = [];
|
|
188
|
+
lines.push("# Agent Task: UI E2E Recovery");
|
|
189
|
+
lines.push("");
|
|
190
|
+
lines.push("## Goal");
|
|
191
|
+
lines.push("Fix target project implementation so ui acceptance passes.");
|
|
192
|
+
lines.push("");
|
|
193
|
+
lines.push("## Constraints");
|
|
194
|
+
lines.push("- Must run ui acceptance after code changes.");
|
|
195
|
+
lines.push("- Do not bypass by lowering thresholds unless explicitly requested.");
|
|
196
|
+
lines.push("- Prioritize real component/contract/recipe fixes.");
|
|
197
|
+
lines.push("");
|
|
198
|
+
lines.push("## Context");
|
|
199
|
+
lines.push(`- targetProject: ${normalizeSlash(payload.targetProject || "")}`);
|
|
200
|
+
lines.push(`- mode: ${payload.mode || "single"}`);
|
|
201
|
+
lines.push(`- profile: ${payload.profile || "standard"}`);
|
|
202
|
+
lines.push(`- autoEnsureOnMiss: ${payload.autoEnsureOnMiss ? "true" : "false"}`);
|
|
203
|
+
lines.push(`- fixLoop: ${Number(payload.fixLoop || 0)}`);
|
|
204
|
+
lines.push("");
|
|
205
|
+
lines.push("## Cases");
|
|
206
|
+
(payload.cases || []).forEach((entry, idx) => {
|
|
207
|
+
lines.push(`### Case ${idx + 1}`);
|
|
208
|
+
lines.push(`- cacheKey: ${entry.cacheKey || ""}`);
|
|
209
|
+
lines.push(`- targetPath: ${normalizeSlash(entry.targetPath || "")}`);
|
|
210
|
+
lines.push(`- reason: ${entry.reason || "unknown"}`);
|
|
211
|
+
if (entry.attemptLogs && entry.attemptLogs.length) {
|
|
212
|
+
lines.push("- attemptLogs:");
|
|
213
|
+
entry.attemptLogs.forEach((log) => {
|
|
214
|
+
lines.push(
|
|
215
|
+
` - attempt ${log.attempt}: ${log.ok ? "ok" : "fail"}${log.reason ? ` (${log.reason})` : ""}`
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
lines.push("");
|
|
220
|
+
});
|
|
221
|
+
lines.push("## Required Command");
|
|
222
|
+
lines.push("Run this command in toolchain repo after fixes:");
|
|
223
|
+
lines.push("");
|
|
224
|
+
lines.push("```bash");
|
|
225
|
+
lines.push(payload.retryCommand || "npm run figma:ui:e2e:cross -- --target-project=<...>");
|
|
226
|
+
lines.push("```");
|
|
227
|
+
lines.push("");
|
|
228
|
+
lines.push("## Completion Criteria");
|
|
229
|
+
lines.push("- e2e command exits with code 0");
|
|
230
|
+
lines.push("- summaryStatus is healthy");
|
|
231
|
+
lines.push("- no unresolved blocking items");
|
|
232
|
+
lines.push("");
|
|
233
|
+
|
|
234
|
+
fs.mkdirSync(path.dirname(taskPath), { recursive: true });
|
|
235
|
+
fs.writeFileSync(taskPath, `${lines.join("\n")}\n`, "utf8");
|
|
236
|
+
return taskPath;
|
|
237
|
+
}
|
|
238
|
+
|
|
167
239
|
function parseCacheKey(cacheKey) {
|
|
168
240
|
const value = String(cacheKey || "").trim();
|
|
169
241
|
const [fileKey, nodeId] = value.split("#");
|
|
@@ -260,6 +332,9 @@ function runSingleCase(input, context) {
|
|
|
260
332
|
if (!targetPath) {
|
|
261
333
|
throw new Error(`batch item ${cacheKey} missing target path`);
|
|
262
334
|
}
|
|
335
|
+
if (!fs.existsSync(targetPath)) {
|
|
336
|
+
throw new Error(`batch item ${cacheKey} target path does not exist: ${targetPath}`);
|
|
337
|
+
}
|
|
263
338
|
|
|
264
339
|
const acceptArgs = [
|
|
265
340
|
`--cacheKey=${cacheKey}`,
|
|
@@ -301,6 +376,18 @@ function runSingleCase(input, context) {
|
|
|
301
376
|
try {
|
|
302
377
|
acceptanceJson = JSON.parse(acceptanceOutput);
|
|
303
378
|
} catch {}
|
|
379
|
+
if (
|
|
380
|
+
!options.allowSkippedCodeLevelComparison &&
|
|
381
|
+
acceptanceJson &&
|
|
382
|
+
Array.isArray(acceptanceJson.warnings) &&
|
|
383
|
+
acceptanceJson.warnings.some((entry) =>
|
|
384
|
+
/code-level comparison skipped/i.test(String(entry || ""))
|
|
385
|
+
)
|
|
386
|
+
) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
`acceptance produced skipped code-level comparison for ${cacheKey}; target linkage is invalid`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
304
391
|
attemptLogs.push({ attempt, ok: true });
|
|
305
392
|
return {
|
|
306
393
|
ok: true,
|
|
@@ -344,6 +431,10 @@ function run() {
|
|
|
344
431
|
console.error("cross-project-e2e failed: --target is required for real component validation");
|
|
345
432
|
process.exit(FAIL_EXIT_CODE);
|
|
346
433
|
}
|
|
434
|
+
if (!fs.existsSync(targetPath)) {
|
|
435
|
+
console.error(`cross-project-e2e failed: --target path does not exist: ${targetPath}`);
|
|
436
|
+
process.exit(FAIL_EXIT_CODE);
|
|
437
|
+
}
|
|
347
438
|
const cacheKey = resolveCacheKey(options);
|
|
348
439
|
if (!cacheKey) {
|
|
349
440
|
console.error("cross-project-e2e failed: provide --cacheKey or (--fileKey + --nodeId)");
|
|
@@ -352,6 +443,7 @@ function run() {
|
|
|
352
443
|
}
|
|
353
444
|
|
|
354
445
|
let tarballPath = "";
|
|
446
|
+
let taskPayload = null;
|
|
355
447
|
try {
|
|
356
448
|
tarballPath = npmPackAndGetTarball();
|
|
357
449
|
runCommand(`npm i -D "${tarballPath}"`, targetProject);
|
|
@@ -404,11 +496,26 @@ function run() {
|
|
|
404
496
|
caseFailures.push({
|
|
405
497
|
index: indexNo,
|
|
406
498
|
cacheKey: entry && (entry.cacheKey || resolveCacheKey(entry)),
|
|
499
|
+
targetPath: entry && entry.target,
|
|
500
|
+
attemptLogs: [],
|
|
407
501
|
reason: error.message,
|
|
408
502
|
});
|
|
409
503
|
}
|
|
410
504
|
});
|
|
411
505
|
if (caseFailures.length) {
|
|
506
|
+
taskPayload = {
|
|
507
|
+
targetProject,
|
|
508
|
+
mode: isBatchMode ? "batch" : "single",
|
|
509
|
+
profile: options.profile || "standard",
|
|
510
|
+
autoEnsureOnMiss: options.autoEnsureOnMiss,
|
|
511
|
+
fixLoop: options.fixLoop,
|
|
512
|
+
cases: caseFailures,
|
|
513
|
+
retryCommand: `npm run figma:ui:e2e:cross -- --target-project=${normalizeSlash(
|
|
514
|
+
targetProject
|
|
515
|
+
)}${options.batchFile ? ` --batch-file=${normalizeSlash(options.batchFile)}` : ""}${
|
|
516
|
+
options.autoEnsureOnMiss ? " --auto-ensure-on-miss" : ""
|
|
517
|
+
}${options.fixLoop ? ` --fix-loop=${options.fixLoop}` : ""}`,
|
|
518
|
+
};
|
|
412
519
|
throw new Error(`batch cases failed: ${JSON.stringify(caseFailures)}`);
|
|
413
520
|
}
|
|
414
521
|
|
|
@@ -424,9 +531,9 @@ function run() {
|
|
|
424
531
|
completeness: options.completeness,
|
|
425
532
|
tarballPath,
|
|
426
533
|
reports: {
|
|
427
|
-
preflight: path.join(reportBase, "ui-preflight-report.json"),
|
|
428
|
-
audit: path.join(reportBase, "ui-1to1-report.json"),
|
|
429
|
-
summary: path.join(reportBase, "ui-quality-summary.json"),
|
|
534
|
+
preflight: path.join(reportBase, "runtime", "ui-preflight-report.json"),
|
|
535
|
+
audit: path.join(reportBase, "runtime", "ui-1to1-report.json"),
|
|
536
|
+
summary: path.join(reportBase, "runtime", "ui-quality-summary.json"),
|
|
430
537
|
},
|
|
431
538
|
cases: caseResults,
|
|
432
539
|
};
|
|
@@ -438,8 +545,42 @@ function run() {
|
|
|
438
545
|
}
|
|
439
546
|
console.log(JSON.stringify(output, null, 2));
|
|
440
547
|
} catch (error) {
|
|
548
|
+
let taskPath = "";
|
|
549
|
+
if (options.emitAgentTaskOnFail) {
|
|
550
|
+
try {
|
|
551
|
+
const payload =
|
|
552
|
+
taskPayload ||
|
|
553
|
+
({
|
|
554
|
+
targetProject,
|
|
555
|
+
mode: isBatchMode ? "batch" : "single",
|
|
556
|
+
profile: options.profile || "standard",
|
|
557
|
+
autoEnsureOnMiss: options.autoEnsureOnMiss,
|
|
558
|
+
fixLoop: options.fixLoop,
|
|
559
|
+
cases: [
|
|
560
|
+
{
|
|
561
|
+
cacheKey: resolveCacheKey(options),
|
|
562
|
+
targetPath: options.target,
|
|
563
|
+
reason: error.message,
|
|
564
|
+
},
|
|
565
|
+
],
|
|
566
|
+
retryCommand: `npm run figma:ui:e2e:cross -- --target-project=${normalizeSlash(
|
|
567
|
+
targetProject
|
|
568
|
+
)}${options.batchFile ? ` --batch-file=${normalizeSlash(options.batchFile)}` : ""}${
|
|
569
|
+
options.cacheKey ? ` --cacheKey=${options.cacheKey}` : ""
|
|
570
|
+
}${options.fileKey ? ` --fileKey=${options.fileKey}` : ""}${
|
|
571
|
+
options.nodeId ? ` --nodeId=${options.nodeId}` : ""
|
|
572
|
+
}${options.target ? ` --target=${normalizeSlash(options.target)}` : ""}${
|
|
573
|
+
options.autoEnsureOnMiss ? " --auto-ensure-on-miss" : ""
|
|
574
|
+
}${options.fixLoop ? ` --fix-loop=${options.fixLoop}` : ""} --emit-agent-task-on-fail`,
|
|
575
|
+
});
|
|
576
|
+
taskPath = writeAgentTask(targetProject, options, payload);
|
|
577
|
+
} catch {}
|
|
578
|
+
}
|
|
441
579
|
console.error("cross-project-e2e failed:");
|
|
442
580
|
console.error(`- ${error.message}`);
|
|
581
|
+
if (taskPath) {
|
|
582
|
+
console.error(`- agent task emitted: ${normalizeSlash(taskPath)}`);
|
|
583
|
+
}
|
|
443
584
|
process.exit(FAIL_EXIT_CODE);
|
|
444
585
|
} finally {
|
|
445
586
|
if (tarballPath && !options.keepPackage) {
|
package/scripts/ui-1to1-audit.js
CHANGED
|
@@ -11,7 +11,7 @@ const ROOT = process.cwd();
|
|
|
11
11
|
const CACHE_DIR_INPUT = process.env.FIGMA_CACHE_DIR || "figma-cache";
|
|
12
12
|
const INDEX_FILE_NAME = process.env.FIGMA_CACHE_INDEX_FILE || "index.json";
|
|
13
13
|
const DEFAULT_CONTRACT_PATH = "figma-cache/adapters/ui-adapter.contract.json";
|
|
14
|
-
const DEFAULT_REPORT_PATH = "figma-cache/reports/ui-1to1-report.json";
|
|
14
|
+
const DEFAULT_REPORT_PATH = "figma-cache/reports/runtime/ui-1to1-report.json";
|
|
15
15
|
const DEFAULT_MIN_SCORE = 85;
|
|
16
16
|
const DEFAULT_RECIPES_DIR = "figma-cache/adapters/recipes";
|
|
17
17
|
const FAIL_EXIT_CODE = 2;
|
|
@@ -105,13 +105,13 @@ function buildReportPaths(options) {
|
|
|
105
105
|
const cacheDir = resolveMaybeAbsolutePath(CACHE_DIR_INPUT);
|
|
106
106
|
return {
|
|
107
107
|
preflight: resolveMaybeAbsolutePath(
|
|
108
|
-
options.preflightReport || path.join(cacheDir, "reports", "ui-preflight-report.json")
|
|
108
|
+
options.preflightReport || path.join(cacheDir, "reports", "runtime", "ui-preflight-report.json")
|
|
109
109
|
),
|
|
110
110
|
audit: resolveMaybeAbsolutePath(
|
|
111
|
-
options.auditReport || path.join(cacheDir, "reports", "ui-1to1-report.json")
|
|
111
|
+
options.auditReport || path.join(cacheDir, "reports", "runtime", "ui-1to1-report.json")
|
|
112
112
|
),
|
|
113
113
|
summary: resolveMaybeAbsolutePath(
|
|
114
|
-
options.summaryReport || path.join(cacheDir, "reports", "ui-quality-summary.json")
|
|
114
|
+
options.summaryReport || path.join(cacheDir, "reports", "runtime", "ui-quality-summary.json")
|
|
115
115
|
),
|
|
116
116
|
};
|
|
117
117
|
}
|
package/scripts/ui-preflight.js
CHANGED
|
@@ -10,7 +10,7 @@ const ROOT = process.cwd();
|
|
|
10
10
|
const CACHE_DIR_INPUT = process.env.FIGMA_CACHE_DIR || "figma-cache";
|
|
11
11
|
const INDEX_FILE_NAME = process.env.FIGMA_CACHE_INDEX_FILE || "index.json";
|
|
12
12
|
const DEFAULT_CONTRACT_PATH = "figma-cache/adapters/ui-adapter.contract.json";
|
|
13
|
-
const DEFAULT_REPORT_PATH = "figma-cache/reports/ui-preflight-report.json";
|
|
13
|
+
const DEFAULT_REPORT_PATH = "figma-cache/reports/runtime/ui-preflight-report.json";
|
|
14
14
|
const BLOCKING_EXIT_CODE = 2;
|
|
15
15
|
|
|
16
16
|
function normalizeSlash(input) {
|
|
@@ -8,7 +8,7 @@ const { getUiProfileConfig } = require("./ui-profile");
|
|
|
8
8
|
|
|
9
9
|
const ROOT = process.cwd();
|
|
10
10
|
const CACHE_DIR_INPUT = process.env.FIGMA_CACHE_DIR || "figma-cache";
|
|
11
|
-
const DEFAULT_OUTPUT_PATH = "figma-cache/reports/ui-quality-summary.json";
|
|
11
|
+
const DEFAULT_OUTPUT_PATH = "figma-cache/reports/runtime/ui-quality-summary.json";
|
|
12
12
|
|
|
13
13
|
function resolveMaybeAbsolutePath(input) {
|
|
14
14
|
if (!input) {
|
|
@@ -62,10 +62,10 @@ function run() {
|
|
|
62
62
|
const options = parseArgs(process.argv.slice(2));
|
|
63
63
|
const cacheDir = resolveMaybeAbsolutePath(CACHE_DIR_INPUT);
|
|
64
64
|
const preflightPath = resolveMaybeAbsolutePath(
|
|
65
|
-
options.preflightReport || path.join(cacheDir, "reports", "ui-preflight-report.json")
|
|
65
|
+
options.preflightReport || path.join(cacheDir, "reports", "runtime", "ui-preflight-report.json")
|
|
66
66
|
);
|
|
67
67
|
const auditPath = resolveMaybeAbsolutePath(
|
|
68
|
-
options.auditReport || path.join(cacheDir, "reports", "ui-1to1-report.json")
|
|
68
|
+
options.auditReport || path.join(cacheDir, "reports", "runtime", "ui-1to1-report.json")
|
|
69
69
|
);
|
|
70
70
|
const outputPath = resolveMaybeAbsolutePath(options.output);
|
|
71
71
|
const profileConfig = getUiProfileConfig();
|