@cimplify/cli 0.15.2 → 0.16.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.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -2
  3. package/dist/add-SXC6RUPQ.mjs +140 -0
  4. package/dist/{add-KRIIKAS4.mjs → add-XQVQLD3F.mjs} +4 -4
  5. package/dist/ai-NQH5L4I6.mjs +17 -0
  6. package/dist/{assets-CWB72PZG.mjs → assets-FZGVOQXH.mjs} +12 -7
  7. package/dist/{auth-step-up-Z6KOTTV7.mjs → auth-step-up-67LCPDNL.mjs} +5 -5
  8. package/dist/build-J4ZUIOPX.mjs +625 -0
  9. package/dist/{cancel-ZHVVILOU.mjs → cancel-VGJHZJ4J.mjs} +4 -4
  10. package/dist/capture-RAJ2B3BH.mjs +69 -0
  11. package/dist/chunk-25ZPFHLF.mjs +51 -0
  12. package/dist/chunk-47ZXSY47.mjs +52 -0
  13. package/dist/{chunk-NK6VC264.mjs → chunk-54J3XR4T.mjs} +2 -2
  14. package/dist/chunk-5HP2INMY.mjs +10631 -0
  15. package/dist/chunk-7JR6JCFF.mjs +32 -0
  16. package/dist/chunk-7PQL7E7K.mjs +68 -0
  17. package/dist/chunk-AKACUJ3W.mjs +81 -0
  18. package/dist/chunk-BYNE553A.mjs +2945 -0
  19. package/dist/{chunk-NYXA6X56.mjs → chunk-CLQYPTJ2.mjs} +31 -11
  20. package/dist/chunk-CNZAOVSK.mjs +104 -0
  21. package/dist/chunk-CPBESPWK.mjs +5576 -0
  22. package/dist/{chunk-GRR5U2M5.mjs → chunk-DYWUPHV3.mjs} +11 -7
  23. package/dist/chunk-EAV2P4N3.mjs +1941 -0
  24. package/dist/{chunk-KN2YSKXZ.mjs → chunk-EDZSOL5O.mjs} +14 -6
  25. package/dist/chunk-EGQIPYUN.mjs +696 -0
  26. package/dist/{chunk-DMLQBAGC.mjs → chunk-EOO4UOQD.mjs} +1 -1
  27. package/dist/chunk-EYEMPIMP.mjs +74 -0
  28. package/dist/chunk-G2ZEFSQJ.mjs +46 -0
  29. package/dist/{chunk-TH4XENKH.mjs → chunk-I4HNHPEM.mjs} +1 -1
  30. package/dist/chunk-JEVSFNPT.mjs +363 -0
  31. package/dist/chunk-JKECUAAV.mjs +2169 -0
  32. package/dist/chunk-KMHORI4Y.mjs +638 -0
  33. package/dist/chunk-KNPYBZ6B.mjs +502 -0
  34. package/dist/{chunk-3QUK5BPY.mjs → chunk-KOD4GBQ5.mjs} +8 -1
  35. package/dist/chunk-KQNZKV6E.mjs +535 -0
  36. package/dist/{chunk-MXYUAJEW.mjs → chunk-LLRUOIMU.mjs} +5 -2
  37. package/dist/{chunk-F2UI225N.mjs → chunk-LNMITJ4Z.mjs} +6 -6
  38. package/dist/chunk-MEM3MDV4.mjs +6463 -0
  39. package/dist/chunk-NY4YT7O6.mjs +84 -0
  40. package/dist/{chunk-A6WHBSXZ.mjs → chunk-Q6CF4C3E.mjs} +15 -13
  41. package/dist/chunk-RP66A52P.mjs +86 -0
  42. package/dist/{chunk-I2UP7YTG.mjs → chunk-SAXGWS2K.mjs} +1 -1
  43. package/dist/chunk-SCKQ4XSD.mjs +41 -0
  44. package/dist/chunk-SF44L2OD.mjs +1152 -0
  45. package/dist/chunk-SGT5IJVW.mjs +28 -0
  46. package/dist/{chunk-WEAB6HHQ.mjs → chunk-SS4JTMIV.mjs} +8 -8
  47. package/dist/chunk-T4MW3PD4.mjs +1456 -0
  48. package/dist/chunk-THATLMEX.mjs +1227 -0
  49. package/dist/{chunk-MLE4MVYC.mjs → chunk-TT4YI33G.mjs} +2 -2
  50. package/dist/chunk-TYV2SVFN.mjs +101 -0
  51. package/dist/chunk-VHK7WBO3.mjs +189 -0
  52. package/dist/chunk-VSA44UKR.mjs +391 -0
  53. package/dist/chunk-XL54SQJ3.mjs +42 -0
  54. package/dist/{chunk-5KYR6WJB.mjs → chunk-XQAHREKO.mjs} +17 -1
  55. package/dist/chunk-ZUCDXRFI.mjs +2011 -0
  56. package/dist/create-4S2EAUR3.mjs +10 -0
  57. package/dist/credits-NJOAOPPW.mjs +33 -0
  58. package/dist/{deploy-JE6TUYCL.mjs → deploy-26Y4UGZZ.mjs} +14 -14
  59. package/dist/dev-MOYURRWQ.mjs +401 -0
  60. package/dist/dev-WL43Q7VD.mjs +8 -0
  61. package/dist/dispatcher.mjs +131 -30
  62. package/dist/{doctor-HFB4IBYK.mjs → doctor-E6ETD2GJ.mjs} +12 -19
  63. package/dist/{domains-BZKGIDF4.mjs → domains-LOTQMVOR.mjs} +6 -6
  64. package/dist/engine-runtime-fetch-CIE7S7PB.mjs +10 -0
  65. package/dist/{env-FZNXKLGL.mjs → env-3PDFC5XF.mjs} +7 -7
  66. package/dist/env-MOTYOPM5.mjs +19 -0
  67. package/dist/explain-K5QEVWCD.mjs +251 -0
  68. package/dist/{inspect-X3M7WSTL.mjs → inspect-Q3E2DHYY.mjs} +3 -3
  69. package/dist/inspect-SJ4WBAXO.mjs +86 -0
  70. package/dist/introspect-7F34YN5V.mjs +9 -0
  71. package/dist/kernel-DEGWMHFL.mjs +662 -0
  72. package/dist/kernel-plugin.js +6862 -0
  73. package/dist/keys-W5SN3DPK.mjs +71 -0
  74. package/dist/lines-XGJYTQ7P.mjs +56 -0
  75. package/dist/{link-4NM2QMI5.mjs → link-NKUAVNM2.mjs} +6 -5
  76. package/dist/{lint-DDZ7HUQN.mjs → lint-G4YPQSSO.mjs} +2 -2
  77. package/dist/{list-2MFOQKKQ.mjs → list-TDR7K2JB.mjs} +3 -3
  78. package/dist/lock-EJPW2LM3.mjs +57 -0
  79. package/dist/{login-RLMDEWAL.mjs → login-AYLU7JU7.mjs} +10 -8
  80. package/dist/{logout-Z57X6HPE.mjs → logout-3M6VMHLH.mjs} +2 -2
  81. package/dist/{logs-36BLYJHJ.mjs → logs-4EL5SOXN.mjs} +5 -5
  82. package/dist/logs-4QQGG2XY.mjs +44 -0
  83. package/dist/mcp-4R2R6E5M.mjs +1077 -0
  84. package/dist/{mock-EVER34IX.mjs → mock-AK24GSP2.mjs} +2 -2
  85. package/dist/outdated-JEKCVLTG.mjs +58 -0
  86. package/dist/port-SBZ7X3EH.mjs +2408 -0
  87. package/dist/{projects-4XRNHJAH.mjs → projects-7JKTC5WJ.mjs} +9 -7
  88. package/dist/publish-QQCX47HK.mjs +20 -0
  89. package/dist/remix-NLLYD3BI.mjs +125 -0
  90. package/dist/repo-Z4G4EW3N.mjs +9 -0
  91. package/dist/report-M7F4ZYP7.mjs +2 -0
  92. package/dist/rollback-2WQ2CW7T.mjs +43 -0
  93. package/dist/{rollback-WCRWXSE3.mjs → rollback-ZGU32HGT.mjs} +6 -6
  94. package/dist/scene-HXARHUM7.mjs +324 -0
  95. package/dist/{status-VA326DWD.mjs → status-C3ZSLZ7Q.mjs} +5 -5
  96. package/dist/status-WEQOC25K.mjs +18 -0
  97. package/dist/test-ZPBWV4VX.mjs +233 -0
  98. package/dist/testers-A3LMXOJJ.mjs +49 -0
  99. package/dist/{unlink-H3BO3DOQ.mjs → unlink-4G4FE4RJ.mjs} +2 -2
  100. package/dist/{update-YYOTN7MG.mjs → update-GHKKM5FS.mjs} +4 -4
  101. package/dist/{whoami-CQPPARRS.mjs → whoami-3QQN6G2A.mjs} +3 -3
  102. package/dist/workshop-CD74D2LK.mjs +1703 -0
  103. package/package.json +11 -7
  104. package/templates/storefront-auto/app/products/[slug]/page.tsx +1 -1
  105. package/templates/storefront-auto/package.json +1 -1
  106. package/templates/storefront-bakery/package.json +1 -1
  107. package/templates/storefront-fashion/app/products/[slug]/page.tsx +1 -1
  108. package/templates/storefront-fashion/package.json +1 -1
  109. package/templates/storefront-grocery/package.json +1 -1
  110. package/templates/storefront-pharmacy/app/products/[slug]/page.tsx +1 -1
  111. package/templates/storefront-pharmacy/package.json +1 -1
  112. package/templates/storefront-restaurant/package.json +1 -1
  113. package/templates/storefront-retail/app/products/[slug]/page.tsx +1 -1
  114. package/templates/storefront-retail/package.json +1 -1
  115. package/templates/storefront-services/package.json +1 -1
  116. package/dist/chunk-ARIDYKLO.mjs +0 -6463
  117. package/dist/dev-V7JSUVOI.mjs +0 -8
  118. package/dist/explain-O5AC73EE.mjs +0 -251
  119. package/dist/introspect-2NGESQZE.mjs +0 -8
  120. package/dist/repo-X3KZ5R64.mjs +0 -9
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import { commonOptions } from './chunk-XL54SQJ3.mjs';
3
+ import { readinessSummary } from './chunk-47ZXSY47.mjs';
4
+ import { FINAL_CAPTURE, prepareSession, runSession, writeCapture, CAPTURE_SCHEMA } from './chunk-TYV2SVFN.mjs';
5
+ import { SessionError } from './chunk-KNPYBZ6B.mjs';
6
+ import { EMPTY_READINESS } from './chunk-BYNE553A.mjs';
7
+ import './chunk-NY4YT7O6.mjs';
8
+ import './chunk-SF44L2OD.mjs';
9
+ import './chunk-VSA44UKR.mjs';
10
+ import './chunk-EGQIPYUN.mjs';
11
+ import './chunk-SCKQ4XSD.mjs';
12
+ import { workPath, requireInteractiveProject } from './chunk-CPBESPWK.mjs';
13
+ import './chunk-VHK7WBO3.mjs';
14
+ import './chunk-5HP2INMY.mjs';
15
+ import './chunk-JKECUAAV.mjs';
16
+ import './chunk-THATLMEX.mjs';
17
+ import './chunk-T4MW3PD4.mjs';
18
+ import './chunk-KQNZKV6E.mjs';
19
+ import './chunk-G2ZEFSQJ.mjs';
20
+ import './chunk-ZUCDXRFI.mjs';
21
+ import './chunk-EYEMPIMP.mjs';
22
+ import './chunk-AKACUJ3W.mjs';
23
+ import './chunk-25ZPFHLF.mjs';
24
+ import './chunk-SGT5IJVW.mjs';
25
+ import { parseArgs, flagString, flagBool } from './chunk-XQAHREKO.mjs';
26
+ import './chunk-CLQYPTJ2.mjs';
27
+ import './chunk-TT4YI33G.mjs';
28
+ import { success, warn, info, dim, result, CliError, CLI_ERROR_CODE } from './chunk-KOD4GBQ5.mjs';
29
+ import path from 'path';
30
+
31
+ var CAPTURE_DIR = "captures";
32
+ var PNG = ".png";
33
+ function capturePath(root, out, device, frame, name) {
34
+ const base = out === void 0 ? workPath(root, CAPTURE_DIR, `${device}-f${frame}${PNG}`) : path.resolve(root, out.endsWith(PNG) ? out : `${out}${PNG}`);
35
+ if (name === FINAL_CAPTURE) return base;
36
+ return `${base.slice(0, -PNG.length)}-${name}${PNG}`;
37
+ }
38
+ async function run(argv) {
39
+ const args = parseArgs(argv);
40
+ const root = process.cwd();
41
+ requireInteractiveProject(root, "capture");
42
+ const options = await commonOptions(args, root);
43
+ const out = flagString(args, "out");
44
+ try {
45
+ const setup = await prepareSession(root);
46
+ const frames = await runSession(setup, { ...options, screenshots: true, inspect: !flagBool(args, "no-inspect") });
47
+ const final = frames.find((f) => f.sidecar.name === FINAL_CAPTURE)?.sidecar.frame ?? options.frame;
48
+ const captures = [];
49
+ const files = [];
50
+ for (const frame of frames) {
51
+ const file = capturePath(root, out, options.device.name, final, frame.sidecar.name);
52
+ captures.push(await writeCapture(frame, file));
53
+ files.push(path.relative(root, file));
54
+ success(`${frame.sidecar.name}: frame ${frame.sidecar.frame} on ${options.device.name} -> ${path.relative(root, file)}`);
55
+ if (frame.inspect !== null && frame.inspect.checks.findings.length > 0) warn(`${frame.inspect.checks.findings.length} UI findings; run \`cimplify inspect\` for the list`);
56
+ }
57
+ info(dim("Each PNG has a JSON sidecar with the frame, clock, seed, device, back-end, readiness and the UI tree"));
58
+ const readiness = frames.find((f) => f.sidecar.name === FINAL_CAPTURE)?.sidecar.readiness ?? frames[frames.length - 1]?.sidecar.readiness ?? EMPTY_READINESS;
59
+ info(readinessSummary(readiness));
60
+ if (readiness.stall_frames > 0) warn(`${readiness.stall_frames} streaming stall frames (a needed chunk was not resident), first at frame ${readiness.stalls[0]}`);
61
+ const body = { schema: CAPTURE_SCHEMA, captures, files, readiness };
62
+ result(body);
63
+ } catch (error) {
64
+ if (error instanceof SessionError) throw new CliError(CLI_ERROR_CODE.BUILD_FAILED, error.message);
65
+ throw error;
66
+ }
67
+ }
68
+
69
+ export { capturePath, run as default };
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ import { createHash } from 'crypto';
3
+
4
+ var DIGEST_PATTERN = /^[0-9a-f]{64}$/;
5
+ function sha256(bytes) {
6
+ return createHash("sha256").update(bytes).digest("hex");
7
+ }
8
+ function hasher() {
9
+ return createHash("sha256");
10
+ }
11
+ function finish(hash) {
12
+ return hash.digest("hex");
13
+ }
14
+ function isDigest(value) {
15
+ return DIGEST_PATTERN.test(value);
16
+ }
17
+ function digestHex(digest) {
18
+ if (!isDigest(digest)) throw new Error(`not a lowercase hex sha256 digest: ${digest}`);
19
+ return digest;
20
+ }
21
+ function canonicalJson(value) {
22
+ if (value === null || typeof value === "boolean" || typeof value === "string") return JSON.stringify(value);
23
+ if (typeof value === "number") {
24
+ if (!Number.isFinite(value)) throw new Error("canonical JSON cannot hold a non-finite number");
25
+ return JSON.stringify(value);
26
+ }
27
+ if (Array.isArray(value)) {
28
+ let out2 = "[";
29
+ for (let i = 0; i < value.length; i++) out2 += (i === 0 ? "" : ",") + canonicalJson(value[i]);
30
+ return `${out2}]`;
31
+ }
32
+ const record = value;
33
+ const keys = Object.keys(record).sort(compareStrings);
34
+ let out = "{";
35
+ for (let i = 0; i < keys.length; i++) {
36
+ out += `${i === 0 ? "" : ","}${JSON.stringify(keys[i])}:${canonicalJson(record[keys[i]])}`;
37
+ }
38
+ return `${out}}`;
39
+ }
40
+ function compareStrings(a, b) {
41
+ const n = a.length < b.length ? a.length : b.length;
42
+ for (let i = 0; i < n; i++) {
43
+ const ca = a.codePointAt(i);
44
+ const cb = b.codePointAt(i);
45
+ if (ca !== cb) return ca < cb ? -1 : 1;
46
+ if (ca > 65535) i++;
47
+ }
48
+ return a.length - b.length;
49
+ }
50
+
51
+ export { canonicalJson, compareStrings, digestHex, finish, hasher, isDigest, sha256 };
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ import { loadScript, parseDevice, DEFAULT_DEVICE, DEFAULT_SEED, DEFAULT_FRAMES } from './chunk-KNPYBZ6B.mjs';
3
+ import { EMPTY_READINESS } from './chunk-BYNE553A.mjs';
4
+ import { existsSync } from 'fs';
5
+ import path from 'path';
6
+
7
+ var READINESS_GATE = "readiness";
8
+ var READINESS_SCRIPTS = ["test/readiness.json", "test/readiness.ts"];
9
+ function kib(bytes) {
10
+ return `${Math.round(bytes / 1024)} KiB`;
11
+ }
12
+ function readinessSummary(readiness) {
13
+ if (readiness.first_frame < 0) return "readiness: the game presented no frame through the game API";
14
+ return `readiness: first frame at frame ${readiness.first_frame} (${Math.round(readiness.first_frame_ms)} ms wall), ${kib(readiness.bytes_before_first_play)} before first play, ${kib(readiness.bytes_total)} total, ${readiness.stall_frames} stall frames in ${readiness.frames}`;
15
+ }
16
+ function readinessScript(root) {
17
+ for (const name of READINESS_SCRIPTS) {
18
+ const file = path.join(root, name);
19
+ if (existsSync(file)) return file;
20
+ }
21
+ return null;
22
+ }
23
+ function judgeReadiness(readiness, maxStalls) {
24
+ const summary = readinessSummary(readiness);
25
+ if (maxStalls !== null && readiness.stall_frames > maxStalls) {
26
+ return { name: READINESS_GATE, status: "failed", detail: `${summary}; the script allows ${maxStalls} (max_stalls), first stalls at frames ${readiness.stalls.slice(0, 8).join(", ")}` };
27
+ }
28
+ return { name: READINESS_GATE, status: "passed", detail: maxStalls === null ? `${summary}; set max_stalls in the script to gate on stalls` : summary };
29
+ }
30
+ async function readinessGate(root, setup, run) {
31
+ const file = readinessScript(root);
32
+ if (file === null) return { name: READINESS_GATE, status: "skipped", detail: `add ${READINESS_SCRIPTS[0]} (an input script along a recorded path) to measure time to first frame, bytes before first play and streaming stalls` };
33
+ const script = await loadScript(file);
34
+ const device = parseDevice(script.devices?.[0] ?? DEFAULT_DEVICE);
35
+ if (typeof device === "string") throw new Error(device);
36
+ const request = {
37
+ device,
38
+ backend: "swiftshader",
39
+ seed: script.seed ?? DEFAULT_SEED,
40
+ scene: script.scene,
41
+ frame: DEFAULT_FRAMES,
42
+ script,
43
+ scriptPath: path.relative(root, file),
44
+ screenshots: false,
45
+ inspect: false
46
+ };
47
+ const frames = await run(setup, request);
48
+ const readiness = frames[frames.length - 1]?.sidecar.readiness ?? EMPTY_READINESS;
49
+ return judgeReadiness(readiness, script.max_stalls ?? null);
50
+ }
51
+
52
+ export { READINESS_GATE, readinessGate, readinessScript, readinessSummary };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { TERMINAL_DEPLOYMENT_STATUSES, DEPLOYMENT_STATUS } from './chunk-MXYUAJEW.mjs';
3
- import { dim, CliError, CLI_ERROR_CODE, failure, success, isJsonMode } from './chunk-3QUK5BPY.mjs';
2
+ import { TERMINAL_DEPLOYMENT_STATUSES, DEPLOYMENT_STATUS } from './chunk-LLRUOIMU.mjs';
3
+ import { dim, CliError, CLI_ERROR_CODE, failure, success, isJsonMode } from './chunk-KOD4GBQ5.mjs';
4
4
 
5
5
  // src/progress.ts
6
6
  var POLL_INTERVAL_MS = 1e3;