stylegallery 0.1.0 → 0.1.2

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 (230) hide show
  1. package/AGENTS.md +4 -1
  2. package/DOMAINS.md +2 -6
  3. package/GOVERNANCE.md +10 -9
  4. package/README.md +29 -127
  5. package/consumer-reference/agent-native/v2/admission-policy.json +646 -0
  6. package/consumer-reference/agent-native/v2/material-registry.json +1 -0
  7. package/consumer-reference/agent-native/v2/schema/admission-policy.schema.json +50 -0
  8. package/consumer-reference/agent-native/v2/schema/material-manifest.schema.json +17 -0
  9. package/consumer-reference/agent-native/v2/schema/material-record.schema.json +20 -0
  10. package/consumer-reference/contract.md +1 -1
  11. package/consumer-reference/index.md +5 -3
  12. package/layout/index.md +124 -0
  13. package/log.md +57 -0
  14. package/package.json +183 -22
  15. package/scripts/agent-native/v2/experimental-extension-registry.mjs +143 -0
  16. package/scripts/agent-native/v2/extensions/a2a-projection.mjs +264 -0
  17. package/scripts/agent-native/v2/extensions/agui-projection.mjs +191 -0
  18. package/scripts/agent-native/v2/material-admission.mjs +295 -0
  19. package/scripts/agent-native/v2/material-cli-adapter.mjs +134 -0
  20. package/scripts/agent-native/v2/material-context.mjs +251 -0
  21. package/scripts/agent-native/v2/material-identity.mjs +71 -0
  22. package/scripts/agent-native/v2/material-mcp-adapter.mjs +253 -0
  23. package/scripts/agent-native/v2/material-operation-registry.mjs +123 -0
  24. package/scripts/agent-native/v2/material-queries.mjs +398 -0
  25. package/scripts/agent-native/v2/material-registry.mjs +319 -0
  26. package/scripts/sg-material-mcp.mjs +98 -0
  27. package/scripts/sg-material.mjs +27 -0
  28. package/consumer-reference/adapters/style-dictionary.config.mjs +0 -36
  29. package/consumer-reference/baselines/calibration.json +0 -260
  30. package/consumer-reference/baselines/manifest.json +0 -21
  31. package/consumer-reference/fixtures/consumer-conformance/e2e-fixture.mjs +0 -282
  32. package/consumer-reference/fixtures/consumer-conformance/manifest.json +0 -102
  33. package/consumer-reference/fixtures/consumer-conformance/runtime-proof.mjs +0 -32
  34. package/consumer-reference/fixtures/consumer-conformance/valid-migration-result.json +0 -18
  35. package/consumer-reference/fixtures/consumer-conformance/valid-migration.json +0 -142
  36. package/consumer-reference/fixtures/invalid-stable-ended-support.json +0 -19
  37. package/consumer-reference/fixtures/promotion/invalid-blocking-evidence.json +0 -26
  38. package/consumer-reference/fixtures/promotion/invalid-count-only.json +0 -29
  39. package/consumer-reference/fixtures/promotion/invalid-missing-owner-migration.json +0 -25
  40. package/consumer-reference/fixtures/promotion/invalid-normative-bypass-no-regression.json +0 -25
  41. package/consumer-reference/fixtures/promotion/invalid-related-counted-independent.json +0 -45
  42. package/consumer-reference/fixtures/promotion/invalid-stable-ended-support.json +0 -26
  43. package/consumer-reference/fixtures/promotion/manifest.json +0 -15
  44. package/consumer-reference/fixtures/promotion/valid-deferred-example.json +0 -67
  45. package/consumer-reference/fixtures/promotion/valid-normative-bypass.json +0 -67
  46. package/consumer-reference/fixtures/token-portability/invalid-cycle.json +0 -7
  47. package/consumer-reference/fixtures/token-portability/invalid-dangling-alias.json +0 -6
  48. package/consumer-reference/fixtures/token-portability/invalid-extends.json +0 -4
  49. package/consumer-reference/fixtures/token-portability/invalid-json-pointer.json +0 -7
  50. package/consumer-reference/fixtures/token-portability/invalid-resolver.json +0 -9
  51. package/consumer-reference/fixtures/token-portability/invalid-type-mismatch.json +0 -10
  52. package/consumer-reference/fixtures/token-portability/invalid-unknown-reserved.json +0 -6
  53. package/consumer-reference/fixtures/token-portability/invalid-untested-type.json +0 -6
  54. package/consumer-reference/fixtures/token-portability/valid-border.json +0 -14
  55. package/consumer-reference/fixtures/token-portability/valid-reference.json +0 -32
  56. package/consumer-reference/fixtures/token-portability/valid-whole-alias.json +0 -7
  57. package/consumer-reference/fixtures/valid-deprecated.json +0 -21
  58. package/consumer-reference/fixtures/valid-experimental.json +0 -19
  59. package/consumer-reference/generated/manifest.json +0 -40
  60. package/consumer-reference/generated/tokens.css +0 -12
  61. package/consumer-reference/policies/shared-experimental.json +0 -37
  62. package/consumer-reference/schema/ax-evidence.schema.json +0 -30
  63. package/consumer-reference/schema/baseline-manifest.schema.json +0 -55
  64. package/consumer-reference/schema/calibration-record.schema.json +0 -190
  65. package/consumer-reference/schema/capture-session.schema.json +0 -161
  66. package/consumer-reference/schema/component-state.schema.json +0 -150
  67. package/consumer-reference/schema/consumer-conformance-record.schema.json +0 -365
  68. package/consumer-reference/schema/dom-evidence.schema.json +0 -38
  69. package/consumer-reference/schema/evidence-record.schema.json +0 -81
  70. package/consumer-reference/schema/fixture-manifest.schema.json +0 -32
  71. package/consumer-reference/schema/item.schema.json +0 -188
  72. package/consumer-reference/schema/page-evidence-manifest.schema.json +0 -216
  73. package/consumer-reference/schema/page-evidence-session.schema.json +0 -119
  74. package/consumer-reference/schema/portable-tokens.schema.json +0 -104
  75. package/consumer-reference/schema/promotion-rfc.schema.json +0 -219
  76. package/consumer-reference/schema/runtime-evidence-manifest.schema.json +0 -33
  77. package/consumer-reference/schema/visual-evidence.schema.json +0 -31
  78. package/design-engineering/consumer-migration-readiness.md +0 -124
  79. package/design-engineering/interface-craft.md +0 -107
  80. package/design-engineering/reference-profiles/external-adaptation/index.md +0 -12
  81. package/design-engineering/reference-profiles/governed-local/editorial/components/button.component.json +0 -125
  82. package/design-engineering/reference-profiles/governed-local/editorial/evidence/button.evidence.json +0 -3504
  83. package/design-engineering/reference-profiles/governed-local/editorial/fixtures/button.fixture.json +0 -65
  84. package/design-engineering/reference-profiles/governed-local/editorial/generated/evidence-coverage.md +0 -23
  85. package/design-engineering/reference-profiles/governed-local/editorial/generated/keyboard-matrix.md +0 -19
  86. package/design-engineering/reference-profiles/governed-local/editorial/generated/state-matrix.md +0 -21
  87. package/design-engineering/reference-profiles/governed-local/editorial/local-foundations.json +0 -12
  88. package/design-engineering/reference-profiles/governed-local/editorial/states/button.states.json +0 -195
  89. package/design-engineering/reference-profiles/governed-local/editorial/tokens.dtcg.json +0 -17
  90. package/design-engineering/reference-profiles/governed-local/terminal/components/button.component.json +0 -125
  91. package/design-engineering/reference-profiles/governed-local/terminal/evidence/button.evidence.json +0 -3504
  92. package/design-engineering/reference-profiles/governed-local/terminal/fixtures/button.fixture.json +0 -65
  93. package/design-engineering/reference-profiles/governed-local/terminal/generated/evidence-coverage.md +0 -23
  94. package/design-engineering/reference-profiles/governed-local/terminal/generated/keyboard-matrix.md +0 -19
  95. package/design-engineering/reference-profiles/governed-local/terminal/generated/state-matrix.md +0 -21
  96. package/design-engineering/reference-profiles/governed-local/terminal/local-foundations.json +0 -12
  97. package/design-engineering/reference-profiles/governed-local/terminal/profile.json +0 -43
  98. package/design-engineering/reference-profiles/governed-local/terminal/states/button.states.json +0 -195
  99. package/design-engineering/reference-profiles/governed-local/terminal/tokens.dtcg.json +0 -17
  100. package/game-ui/classification.md +0 -82
  101. package/game-ui/reference-record.md +0 -62
  102. package/game-ui/screen-hierarchy.md +0 -107
  103. package/game-ui/unity/architecture.md +0 -166
  104. package/game-ui/unity/cli-loop.md +0 -84
  105. package/game-ui/unity/data/unity-technologies-public-repositories.json +0 -26654
  106. package/game-ui/unity/org-wiki.md +0 -146
  107. package/game-ui/unity/repository-map.md +0 -102
  108. package/game-ui/unity/ui-systems.md +0 -85
  109. package/motion/practice-reference.md +0 -145
  110. package/motion/review-workflow.md +0 -86
  111. package/motion/vocabulary.md +0 -82
  112. package/platform-guides/apple-interaction.md +0 -89
  113. package/scripts/agent-native/events.mjs +0 -113
  114. package/scripts/agent-native/immutable-store.mjs +0 -102
  115. package/scripts/artifact-metadata.mjs +0 -20
  116. package/scripts/audit-evidence-freshness.mjs +0 -308
  117. package/scripts/baseline-contract.mjs +0 -189
  118. package/scripts/baseline-schema-parity.mjs +0 -40
  119. package/scripts/build-reference-artifacts.mjs +0 -127
  120. package/scripts/calibration-raw-contract.mjs +0 -172
  121. package/scripts/capture-session-contract.mjs +0 -187
  122. package/scripts/component-state-artifact-fixture.mjs +0 -44
  123. package/scripts/component-state-contract.mjs +0 -99
  124. package/scripts/component-state-semantics.mjs +0 -128
  125. package/scripts/component-state-workflow-contract.mjs +0 -67
  126. package/scripts/component-state-workflow-negative-cases.mjs +0 -64
  127. package/scripts/consumer-conformance-contract.mjs +0 -198
  128. package/scripts/consumer-evidence-governance-contract.mjs +0 -210
  129. package/scripts/consumer-reference-case-runner.mjs +0 -93
  130. package/scripts/consumer-reference-schema.mjs +0 -155
  131. package/scripts/create-component-state-session.mjs +0 -100
  132. package/scripts/create-page-evidence-session.mjs +0 -139
  133. package/scripts/domain-document-boundaries.mjs +0 -40
  134. package/scripts/domain-validation-checks.mjs +0 -141
  135. package/scripts/evidence-artifact-contract.mjs +0 -191
  136. package/scripts/finalize-component-state-evidence.mjs +0 -165
  137. package/scripts/finalize-page-evidence.mjs +0 -197
  138. package/scripts/generate-consumer-reference-evidence.mjs +0 -154
  139. package/scripts/generate-patterns.mjs +0 -218
  140. package/scripts/governance-matrix-contract.mjs +0 -73
  141. package/scripts/governance-matrix-negative-cases.mjs +0 -114
  142. package/scripts/governance-policy-contract.mjs +0 -49
  143. package/scripts/governance-test-fixture.mjs +0 -321
  144. package/scripts/governance-workflow-negative-cases.mjs +0 -241
  145. package/scripts/governed-profile-registry.mjs +0 -125
  146. package/scripts/json-schema-formats.mjs +0 -31
  147. package/scripts/markdown-structure.mjs +0 -45
  148. package/scripts/page-artifact-metadata.mjs +0 -124
  149. package/scripts/page-evidence-contract.mjs +0 -297
  150. package/scripts/page-evidence-fixture.mjs +0 -271
  151. package/scripts/pattern-data.mjs +0 -325
  152. package/scripts/profile-record-contract.mjs +0 -140
  153. package/scripts/promotion-attestation-contract.mjs +0 -91
  154. package/scripts/promotion-boundary-test-contract.mjs +0 -92
  155. package/scripts/promotion-fixture-inventory.mjs +0 -109
  156. package/scripts/promotion-governance-contract.mjs +0 -28
  157. package/scripts/reference-artifact-path-contract.mjs +0 -28
  158. package/scripts/reference-profile-contract.mjs +0 -114
  159. package/scripts/reference-token-contract.mjs +0 -156
  160. package/scripts/run-consumer-page-evidence-ci.mjs +0 -170
  161. package/scripts/summarize-sentinel-calibration.mjs +0 -98
  162. package/scripts/test-agent-adapter-conformance.mjs +0 -250
  163. package/scripts/test-agent-conformance-receipt.mjs +0 -106
  164. package/scripts/test-agent-events.mjs +0 -81
  165. package/scripts/test-agent-execution-effects.mjs +0 -114
  166. package/scripts/test-agent-execution-fixtures.mjs +0 -140
  167. package/scripts/test-agent-execution-kernel.mjs +0 -39
  168. package/scripts/test-agent-execution-learning.mjs +0 -130
  169. package/scripts/test-agent-execution-lifecycle.mjs +0 -143
  170. package/scripts/test-agent-execution-safety.mjs +0 -158
  171. package/scripts/test-agent-execution-views.mjs +0 -117
  172. package/scripts/test-agent-identity-integrity-cases.mjs +0 -160
  173. package/scripts/test-agent-knowledge-kernel.mjs +0 -183
  174. package/scripts/test-agent-learning.mjs +0 -246
  175. package/scripts/test-agent-mcp.mjs +0 -246
  176. package/scripts/test-agent-native-schemas.mjs +0 -215
  177. package/scripts/test-agent-projections.mjs +0 -249
  178. package/scripts/test-agent-registry-mcp-integrity.mjs +0 -215
  179. package/scripts/test-agent-registry-mutations.mjs +0 -110
  180. package/scripts/test-audit-evidence-freshness.mjs +0 -177
  181. package/scripts/test-component-state-sentinel.mjs +0 -35
  182. package/scripts/test-component-state-source-contract.mjs +0 -83
  183. package/scripts/test-consumer-conformance-sentinel.mjs +0 -165
  184. package/scripts/test-consumer-reference-sentinel.mjs +0 -31
  185. package/scripts/test-generate-consumer-reference-evidence.mjs +0 -124
  186. package/scripts/test-json-cli-output.mjs +0 -151
  187. package/scripts/test-json-schema-formats.mjs +0 -40
  188. package/scripts/test-reference-adapters.mjs +0 -199
  189. package/scripts/test-renderer-purity.mjs +0 -34
  190. package/scripts/test-sg-cli.mjs +0 -129
  191. package/scripts/test-summarize-sentinel-calibration.mjs +0 -226
  192. package/scripts/test-validate-baseline-manifest.mjs +0 -234
  193. package/scripts/test-validate-component-state-artifacts.mjs +0 -243
  194. package/scripts/test-validate-component-state.mjs +0 -106
  195. package/scripts/test-validate-consumer-conformance.mjs +0 -427
  196. package/scripts/test-validate-consumer-reference-cli.mjs +0 -69
  197. package/scripts/test-validate-consumer-reference.mjs +0 -263
  198. package/scripts/test-validate-domains.mjs +0 -357
  199. package/scripts/test-validate-governance.mjs +0 -292
  200. package/scripts/test-validate-ia.mjs +0 -262
  201. package/scripts/test-validate-okf.mjs +0 -73
  202. package/scripts/test-validate-page-evidence.mjs +0 -302
  203. package/scripts/test-validate-patterns.mjs +0 -157
  204. package/scripts/test-validate-promotion-rfc.mjs +0 -250
  205. package/scripts/test-validate-reference-profiles.mjs +0 -170
  206. package/scripts/test-validate-unity-org-wiki.mjs +0 -57
  207. package/scripts/test-validate-unity-source-contracts.mjs +0 -67
  208. package/scripts/test-validate-vocabulary.mjs +0 -174
  209. package/scripts/test-validate-webpage-workflow.mjs +0 -293
  210. package/scripts/validate-baseline-manifest.mjs +0 -44
  211. package/scripts/validate-catalog.mjs +0 -65
  212. package/scripts/validate-component-state.mjs +0 -141
  213. package/scripts/validate-consumer-conformance.mjs +0 -477
  214. package/scripts/validate-consumer-reference.mjs +0 -288
  215. package/scripts/validate-domains.mjs +0 -237
  216. package/scripts/validate-governance.mjs +0 -248
  217. package/scripts/validate-ia.mjs +0 -136
  218. package/scripts/validate-links.mjs +0 -66
  219. package/scripts/validate-okf.mjs +0 -104
  220. package/scripts/validate-page-evidence.mjs +0 -191
  221. package/scripts/validate-patterns.mjs +0 -246
  222. package/scripts/validate-promotion-rfc.mjs +0 -224
  223. package/scripts/validate-reference-artifacts.mjs +0 -125
  224. package/scripts/validate-renderer-purity.mjs +0 -56
  225. package/scripts/validate-unity-org-wiki.mjs +0 -146
  226. package/scripts/validate-unity-source-contracts.mjs +0 -107
  227. package/scripts/validate-vocabulary.mjs +0 -115
  228. package/scripts/validate-webpage-workflow.mjs +0 -254
  229. package/scripts/visual-expectation-contract.mjs +0 -20
  230. package/scripts/workflow-action-contract.mjs +0 -163
@@ -1,151 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { spawn } from "node:child_process";
4
- import { createHash } from "node:crypto";
5
- import path from "node:path";
6
- import { fileURLToPath } from "node:url";
7
-
8
- const scriptPath = fileURLToPath(import.meta.url);
9
- const root = path.resolve(path.dirname(scriptPath), "..");
10
- const cases = [
11
- { kind: "validator", script: "validate-consumer-reference.mjs" },
12
- { kind: "harness", script: "test-validate-consumer-reference.mjs" },
13
- ];
14
-
15
- function reportIsComplete(kind, report) {
16
- if (!report || typeof report !== "object" || report.ok !== true) return false;
17
- if (kind === "validator") {
18
- return Number.isInteger(report.checkedItems)
19
- && report.checkedItems > 0
20
- && Array.isArray(report.profiles);
21
- }
22
- return kind === "harness" && Array.isArray(report.results) && report.results.length > 30;
23
- }
24
-
25
- function readStream(stream) {
26
- return new Promise((resolve, reject) => {
27
- stream.setEncoding("utf8");
28
- let output = "";
29
- stream.on("data", (chunk) => { output += chunk; });
30
- stream.once("end", () => resolve(output));
31
- stream.once("error", reject);
32
- });
33
- }
34
-
35
- function waitForClose(child, label) {
36
- return new Promise((resolve, reject) => {
37
- child.once("error", (error) => reject(new Error(`${label} failed to start: ${error.message}`, { cause: error })));
38
- child.once("close", (status, signal) => resolve({ signal, status }));
39
- });
40
- }
41
-
42
- async function parsePipe(kind) {
43
- try {
44
- const output = await readStream(process.stdin);
45
- const report = JSON.parse(output);
46
- const complete = reportIsComplete(kind, report);
47
- const summary = {
48
- bytes: Buffer.byteLength(output),
49
- complete,
50
- digest: createHash("sha256").update(output).digest("hex"),
51
- };
52
- process.stdout.write(`${JSON.stringify(summary)}\n`);
53
- process.exitCode = complete ? 0 : 1;
54
- } catch (error) {
55
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
56
- process.exitCode = 1;
57
- }
58
- }
59
-
60
- async function runPipeCase(testCase, run) {
61
- const producer = spawn(process.execPath, [path.join(root, "scripts", testCase.script), "--json"], {
62
- cwd: root,
63
- stdio: ["ignore", "pipe", "pipe"],
64
- });
65
- const parser = spawn(process.execPath, [scriptPath, "--pipe-parser", testCase.kind], {
66
- cwd: root,
67
- stdio: ["pipe", "pipe", "pipe"],
68
- });
69
- const directOutputPromise = readStream(producer.stdout);
70
- const producerStderrPromise = readStream(producer.stderr);
71
- const parserOutputPromise = readStream(parser.stdout);
72
- const parserStderrPromise = readStream(parser.stderr);
73
- let pipeError = null;
74
- parser.stdin.once("error", (error) => { pipeError = error; });
75
- producer.stdout.pipe(parser.stdin);
76
-
77
- const [producerClose, parserClose, directOutput, producerStderr, parserOutput, parserStderr] = await Promise.all([
78
- waitForClose(producer, `${testCase.kind} producer`),
79
- waitForClose(parser, `${testCase.kind} parser`),
80
- directOutputPromise,
81
- producerStderrPromise,
82
- parserOutputPromise,
83
- parserStderrPromise,
84
- ]);
85
-
86
- let directReport;
87
- let pipeReport;
88
- try {
89
- directReport = JSON.parse(directOutput);
90
- pipeReport = JSON.parse(parserOutput);
91
- } catch (error) {
92
- return {
93
- actual: {
94
- parserStatus: parserClose.status,
95
- parserStderr: parserStderr.trim(),
96
- pipeError: pipeError?.message ?? "",
97
- producerStatus: producerClose.status,
98
- producerStderr: producerStderr.trim(),
99
- },
100
- expected: "complete parseable JSON through a real Node stream pipe",
101
- name: `${testCase.kind}_pipe_run_${run}`,
102
- ok: false,
103
- reason: error instanceof Error ? error.message : String(error),
104
- };
105
- }
106
-
107
- const directBytes = Buffer.byteLength(directOutput);
108
- const directDigest = createHash("sha256").update(directOutput).digest("hex");
109
- const equivalent = pipeReport.bytes === directBytes && pipeReport.digest === directDigest;
110
- const complete = reportIsComplete(testCase.kind, directReport) && pipeReport.complete === true;
111
- return {
112
- actual: {
113
- complete,
114
- directBytes,
115
- equivalent,
116
- parserSignal: parserClose.signal,
117
- parserStatus: parserClose.status,
118
- parserStderr: parserStderr.trim(),
119
- pipeBytes: pipeReport.bytes,
120
- pipeError: pipeError?.message ?? "",
121
- producerSignal: producerClose.signal,
122
- producerStatus: producerClose.status,
123
- producerStderr: producerStderr.trim(),
124
- },
125
- expected: "complete parseable JSON through a real Node stream pipe",
126
- name: `${testCase.kind}_pipe_run_${run}`,
127
- ok: producerClose.status === 0
128
- && producerClose.signal === null
129
- && parserClose.status === 0
130
- && parserClose.signal === null
131
- && producerStderr.length === 0
132
- && parserStderr.length === 0
133
- && pipeError === null
134
- && directBytes > 512
135
- && complete
136
- && equivalent,
137
- };
138
- }
139
-
140
- async function main() {
141
- const results = [];
142
- for (const testCase of cases) {
143
- for (const run of [1, 2]) results.push(await runPipeCase(testCase, run));
144
- }
145
- const report = { ok: results.every((result) => result.ok), results };
146
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
147
- process.exitCode = report.ok ? 0 : 1;
148
- }
149
-
150
- if (process.argv[2] === "--pipe-parser") await parsePipe(process.argv[3]);
151
- else await main();
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import assert from "node:assert/strict";
4
- import test from "node:test";
5
- import Ajv2020 from "ajv/dist/2020.js";
6
- import { addDateTimeFormat, isRfc3339DateTime } from "./json-schema-formats.mjs";
7
-
8
- test("rejects RFC3339 values whose calendar date would normalize", () => {
9
- for (const value of [
10
- "2023-02-29T12:00:00Z",
11
- "2023-02-30T12:00:00Z",
12
- "2024-04-31T12:00:00+05:30",
13
- ]) {
14
- assert.equal(isRfc3339DateTime(value), false, value);
15
- }
16
- });
17
-
18
- test("preserves valid RFC3339 offsets and fractional seconds", () => {
19
- for (const value of [
20
- "2024-02-29T23:59:59Z",
21
- "2024-02-29T23:59:59.123456789+05:30",
22
- "2024-02-29T00:00:00-04:00",
23
- ]) {
24
- assert.equal(isRfc3339DateTime(value), true, value);
25
- }
26
- });
27
-
28
- test("uses the strict validator for the AJV date-time format", () => {
29
- const ajv = new Ajv2020({ allErrors: true, strict: true });
30
- addDateTimeFormat(ajv);
31
- const validate = ajv.compile({
32
- additionalProperties: false,
33
- properties: { at: { format: "date-time", type: "string" } },
34
- required: ["at"],
35
- type: "object",
36
- });
37
-
38
- assert.equal(validate({ at: "2024-02-29T23:59:59.123Z" }), true);
39
- assert.equal(validate({ at: "2023-02-29T23:59:59.123Z" }), false);
40
- });
@@ -1,199 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import crypto from "node:crypto";
4
- import fs from "node:fs";
5
- import os from "node:os";
6
- import path from "node:path";
7
- import { spawnSync } from "node:child_process";
8
- import { fileURLToPath } from "node:url";
9
-
10
- const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11
- const builder = path.join(repositoryRoot, "scripts", "build-reference-artifacts.mjs");
12
- const validator = path.join(repositoryRoot, "scripts", "validate-reference-artifacts.mjs");
13
- const schema = JSON.parse(fs.readFileSync(path.join(repositoryRoot, "consumer-reference/schema/portable-tokens.schema.json"), "utf8"));
14
-
15
- function parseJson(child) {
16
- try {
17
- return JSON.parse(child.stdout);
18
- } catch (error) {
19
- return { failures: [{ code: "invalid_json_output", message: error instanceof Error ? error.message : String(error) }], ok: false };
20
- }
21
- }
22
-
23
- function codes(output) {
24
- return Array.isArray(output.failures)
25
- ? output.failures.flatMap((failure) => typeof failure?.code === "string" ? [failure.code] : [])
26
- : [];
27
- }
28
-
29
- const tempRoot = fs.mkdtempSync(path.join(repositoryRoot, ".tmp-stylegallery-reference-adapter-"));
30
- const results = [];
31
-
32
- function run(command, args) {
33
- const child = spawnSync(process.execPath, [command, ...args, "--json"], { cwd: repositoryRoot, encoding: "utf8" });
34
- return { child, output: parseJson(child) };
35
- }
36
-
37
- function recordAccepted(name, execution, predicate = () => true) {
38
- const actualCodes = codes(execution.output);
39
- const accepted = execution.child.status === 0 && execution.output.ok === true && execution.output.scaffold !== true;
40
- results.push({
41
- actual: { codes: actualCodes, ok: execution.output.ok, scaffold: execution.output.scaffold === true, status: execution.child.status },
42
- expected: "ok:true and exit:0",
43
- name,
44
- ok: accepted && predicate(),
45
- });
46
- }
47
-
48
- function recordRejected(name, execution, expectedCode) {
49
- const actualCodes = codes(execution.output);
50
- results.push({
51
- actual: { codes: actualCodes, ok: execution.output.ok, scaffold: execution.output.scaffold === true, status: execution.child.status },
52
- expected: expectedCode,
53
- name,
54
- ok: execution.child.status !== 0 && execution.output.ok === false && actualCodes.includes(expectedCode),
55
- });
56
- }
57
-
58
- try {
59
- const groupPattern = new RegExp(Object.keys(schema.$defs.group.patternProperties)[0]);
60
- const rootPattern = new RegExp(Object.keys(schema.patternProperties)[0]);
61
- const unsafeSegments = ["__proto__", "prototype", "constructor"];
62
- results.push({
63
- actual: {
64
- groupDescription: schema.$defs.group.properties.$description.type,
65
- tokenDescription: schema.$defs.token.properties.$description.type,
66
- unsafeGroupMatches: unsafeSegments.filter((segment) => groupPattern.test(segment)),
67
- unsafeRootMatches: unsafeSegments.filter((segment) => rootPattern.test(segment)),
68
- },
69
- expected: "string descriptions and no unsafe path segments",
70
- name: "schema_runtime_boundary_parity",
71
- ok: schema.$defs.group.properties.$description.type === "string"
72
- && schema.$defs.token.properties.$description.type === "string"
73
- && unsafeSegments.every((segment) => !groupPattern.test(segment) && !rootPattern.test(segment)),
74
- });
75
- const output = path.join(tempRoot, "tokens.css");
76
- const manifest = path.join(tempRoot, "manifest.json");
77
- const validBuild = run(builder, ["--source", "consumer-reference/fixtures/token-portability/valid-reference.json", "--output", output, "--manifest", manifest, "--adapter", "style-dictionary", "--fail-on-warning"]);
78
- recordAccepted("valid_reference_build", validBuild, () => {
79
- const css = fs.readFileSync(output, "utf8");
80
- return css.includes("var(--color-accent)") && css.includes("var(--space-small)") && !css.includes("[object Object]");
81
- });
82
- recordAccepted("valid_reference_manifest", run(validator, ["--manifest", manifest]));
83
-
84
- for (const fixture of ["valid-whole-alias.json", "valid-border.json"]) {
85
- recordAccepted(fixture.replace(".json", ""), run(builder, ["--source", `consumer-reference/fixtures/token-portability/${fixture}`, "--output", output, "--manifest", manifest, "--fail-on-warning"]));
86
- }
87
- const invalidFixtures = [
88
- ["invalid-extends.json", "token_extends_forbidden"],
89
- ["invalid-json-pointer.json", "token_json_pointer_forbidden"],
90
- ["invalid-resolver.json", "token_resolver_forbidden"],
91
- ["invalid-unknown-reserved.json", "token_unknown_reserved"],
92
- ["invalid-untested-type.json", "token_type_unsupported"],
93
- ["invalid-dangling-alias.json", "alias_dangling"],
94
- ["invalid-cycle.json", "alias_cycle"],
95
- ["invalid-type-mismatch.json", "alias_type_mismatch"],
96
- ];
97
- for (const [fixture, expected] of invalidFixtures) {
98
- recordRejected(fixture.replace(".json", ""), run(builder, ["--source", `consumer-reference/fixtures/token-portability/${fixture}`, "--output", output, "--manifest", manifest, "--fail-on-warning"]), expected);
99
- }
100
-
101
- const invalidUnit = path.join(tempRoot, "invalid-unit.json");
102
- fs.writeFileSync(invalidUnit, '{"space":{"$type":"dimension","bad":{"$value":{"value":1,"unit":"vh"}}}}\n');
103
- recordRejected("invalid_untested_unit", run(builder, ["--source", invalidUnit, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "token_unit_unsupported");
104
- const partialAlias = path.join(tempRoot, "invalid-partial-alias.json");
105
- fs.writeFileSync(partialAlias, '{"space":{"$type":"dimension","bad":{"$value":"calc({space.base} * 2)"}}}\n');
106
- recordRejected("invalid_partial_alias", run(builder, ["--source", partialAlias, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "alias_whole_required");
107
- const invalidGroupDescription = path.join(tempRoot, "invalid-group-description.json");
108
- fs.writeFileSync(invalidGroupDescription, '{"space":{"$description":{"unsafe":true},"$type":"dimension","small":{"$value":{"value":1,"unit":"px"}}}}\n');
109
- recordRejected("invalid_group_description", run(builder, ["--source", invalidGroupDescription, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "token_description_invalid");
110
- const invalidTokenDescription = path.join(tempRoot, "invalid-token-description.json");
111
- fs.writeFileSync(invalidTokenDescription, '{"space":{"$type":"dimension","small":{"$description":42,"$value":{"value":1,"unit":"px"}}}}\n');
112
- recordRejected("invalid_token_description", run(builder, ["--source", invalidTokenDescription, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "token_description_invalid");
113
- const duplicateSourceProperty = path.join(tempRoot, "invalid-duplicate-source-property.json");
114
- fs.writeFileSync(duplicateSourceProperty, '{"space":{"$type":"dimension","$type":"dimension","small":{"$value":{"value":1,"unit":"px"}}}}\n');
115
- recordRejected("duplicate_source_property", run(builder, ["--source", duplicateSourceProperty, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "token_json_invalid");
116
- for (const [name, sourceText] of [
117
- ["constructor", '{"constructor":{"$type":"dimension","small":{"$value":{"value":1,"unit":"px"}}}}\n'],
118
- ["prototype", '{"prototype":{"$type":"dimension","small":{"$value":{"value":1,"unit":"px"}}}}\n'],
119
- ["__proto__", '{"__proto__":{"$type":"dimension","small":{"$value":{"value":1,"unit":"px"}}}}\n'],
120
- ]) {
121
- const unsafePath = path.join(tempRoot, `invalid-path-${name}.json`);
122
- fs.writeFileSync(unsafePath, sourceText);
123
- recordRejected(`invalid_path_${name}`, run(builder, ["--source", unsafePath, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "token_path_segment_unsafe");
124
- }
125
-
126
- const baselineSource = fs.readFileSync(path.join(repositoryRoot, "consumer-reference/fixtures/token-portability/valid-reference.json"), "utf8");
127
- fs.writeFileSync(path.join(tempRoot, "source.json"), baselineSource);
128
- const baselineBuild = run(builder, ["--source", path.join(tempRoot, "source.json"), "--output", output, "--manifest", manifest, "--fail-on-warning"]);
129
- recordAccepted("artifact_baseline", baselineBuild);
130
- const baselineCss = fs.readFileSync(output, "utf8");
131
- const baselineManifest = fs.readFileSync(manifest, "utf8");
132
- fs.writeFileSync(manifest, baselineManifest.replace('"schemaVersion": "1.0",', '"schemaVersion": "1.0",\n "schemaVersion": "1.0",'));
133
- recordRejected("duplicate_manifest_property", run(validator, ["--manifest", manifest]), "artifact_manifest_invalid");
134
- const duplicateValidatorSource = baselineSource.replace('"$type": "color",', '"$type": "color",\n "$type": "color",');
135
- fs.writeFileSync(path.join(tempRoot, "source.json"), duplicateValidatorSource);
136
- const duplicateSourceManifest = JSON.parse(baselineManifest);
137
- duplicateSourceManifest.inputHash = `sha256:${crypto.createHash("sha256").update(duplicateValidatorSource).digest("hex")}`;
138
- fs.writeFileSync(manifest, `${JSON.stringify(duplicateSourceManifest, null, 2)}\n`);
139
- recordRejected("duplicate_validator_source_property", run(validator, ["--manifest", manifest]), "artifact_source_invalid");
140
- fs.writeFileSync(path.join(tempRoot, "source.json"), baselineSource);
141
- fs.writeFileSync(manifest, baselineManifest);
142
- const symlinkSource = path.join(tempRoot, "symlink-source.json");
143
- fs.symlinkSync(path.join(tempRoot, "source.json"), symlinkSource);
144
- recordRejected("symlink_source", run(builder, ["--source", symlinkSource, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "token_source_untrusted");
145
- const realOutput = path.join(tempRoot, "real-tokens.css");
146
- fs.renameSync(output, realOutput);
147
- fs.symlinkSync(realOutput, output);
148
- recordRejected("symlink_validator_output", run(validator, ["--manifest", manifest]), "artifact_output_untrusted");
149
- recordRejected("symlink_builder_output", run(builder, ["--source", path.join(tempRoot, "source.json"), "--output", output, "--manifest", manifest, "--fail-on-warning"]), "artifact_output_untrusted");
150
- fs.rmSync(output);
151
- fs.renameSync(realOutput, output);
152
- const realManifest = path.join(tempRoot, "real-manifest.json");
153
- fs.renameSync(manifest, realManifest);
154
- fs.symlinkSync(realManifest, manifest);
155
- recordRejected("symlink_validator_manifest", run(validator, ["--manifest", manifest]), "artifact_manifest_untrusted");
156
- recordRejected("symlink_builder_manifest", run(builder, ["--source", path.join(tempRoot, "source.json"), "--output", output, "--manifest", manifest, "--fail-on-warning"]), "artifact_manifest_untrusted");
157
- fs.rmSync(manifest);
158
- fs.renameSync(realManifest, manifest);
159
- const outsideRoot = fs.mkdtempSync(path.join(os.tmpdir(), "stylegallery-reference-escape-"));
160
- const escapedSource = path.join(outsideRoot, "source.json");
161
- fs.writeFileSync(escapedSource, baselineSource);
162
- recordRejected("escaped_source", run(builder, ["--source", escapedSource, "--output", output, "--manifest", manifest, "--fail-on-warning"]), "token_source_untrusted");
163
- const escapedOutput = path.join(outsideRoot, "tokens.css");
164
- recordRejected("escaped_output", run(builder, ["--source", path.join(tempRoot, "source.json"), "--output", escapedOutput, "--manifest", manifest, "--fail-on-warning"]), "artifact_output_untrusted");
165
- const escapedManifest = path.join(outsideRoot, "manifest.json");
166
- recordRejected("escaped_manifest", run(builder, ["--source", path.join(tempRoot, "source.json"), "--output", output, "--manifest", escapedManifest, "--fail-on-warning"]), "artifact_manifest_untrusted");
167
- fs.rmSync(outsideRoot, { force: true, recursive: true });
168
- const artifactCases = [
169
- ["no_output", "artifact_output_missing", () => fs.rmSync(output)],
170
- ["zero_count", "artifact_zero_count", (item) => { item.sourceCount = 0; item.outputCount = 0; item.declarations = []; }],
171
- ["warning", "artifact_warning", (item) => { item.warnings = ["synthetic warning"]; }],
172
- ["missing_declaration", "artifact_declaration_missing", (item) => { item.declarations = item.declarations.slice(1); }],
173
- ["duplicate_declaration", "artifact_declaration_duplicate", (item) => { item.declarations.push(item.declarations[0]); }],
174
- ["object_sentinel", "artifact_object_sentinel", () => fs.writeFileSync(output, baselineCss.replace("120ms", "[object Object]"))],
175
- ["unresolved_alias", "artifact_unresolved_value", () => fs.writeFileSync(output, baselineCss.replace("120ms", "{duration.quick}"))],
176
- ["count_mismatch", "artifact_count_mismatch", (item) => { item.outputCount += 1; }],
177
- ["scaffold_manifest", "artifact_scaffold_forbidden", (item) => { item.scaffold = true; }],
178
- ["forged_value", "artifact_source_output_mismatch", (item) => {
179
- const changed = baselineCss.replace("120ms", "999999s !important");
180
- fs.writeFileSync(output, changed);
181
- item.outputHash = `sha256:${crypto.createHash("sha256").update(changed).digest("hex")}`;
182
- item.declarations.find((declaration) => declaration.name === "--duration-quick").value = "999999s !important";
183
- }],
184
- ];
185
- for (const [name, expected, mutate] of artifactCases) {
186
- fs.writeFileSync(output, baselineCss);
187
- const item = JSON.parse(baselineManifest);
188
- mutate(item);
189
- fs.writeFileSync(manifest, `${JSON.stringify(item, null, 2)}\n`);
190
- recordRejected(name, run(validator, ["--manifest", manifest]), expected);
191
- }
192
- } finally {
193
- fs.rmSync(tempRoot, { force: true, recursive: true });
194
- }
195
-
196
- const failures = results.filter((result) => !result.ok).map((result) => `missing_semantic:${result.name}:${result.expected}`);
197
- const report = { failures, ok: failures.length === 0, results };
198
- console.log(JSON.stringify(report, null, 2));
199
- process.exitCode = report.ok ? 0 : 1;
@@ -1,34 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from "node:fs";
4
- import os from "node:os";
5
- import path from "node:path";
6
- import { spawnSync } from "node:child_process";
7
- import { fileURLToPath } from "node:url";
8
-
9
- const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
10
- const validator = path.join(repositoryRoot, "scripts", "validate-renderer-purity.mjs");
11
- const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "stylegallery-pr4-renderer-"));
12
- const cases = [];
13
-
14
- function run(renderer) {
15
- const child = spawnSync(process.execPath, [validator, "--renderer", renderer, "--json"], { cwd: repositoryRoot, encoding: "utf8" });
16
- return { child, output: JSON.parse(child.stdout) };
17
- }
18
-
19
- try {
20
- const valid = run("tests/helpers/render-consumer-reference.mjs");
21
- cases.push({ actual: { codes: valid.output.failures.map((failure) => failure.code), status: valid.child.status }, expected: "pure import and exit:0", name: "canonical_renderer_import", ok: valid.child.status === 0 && valid.output.ok === true });
22
- const mutation = path.join(tempRoot, "render-consumer-reference.mjs");
23
- fs.writeFileSync(mutation, 'import fs from "node:fs";\nimport { patterns } from "../../scripts/pattern-data.mjs";\nfs.appendFileSync("CATALOG.md", "mutation");\nexport { patterns };\n');
24
- const invalid = run(mutation);
25
- const codes = invalid.output.failures.map((failure) => failure.code);
26
- cases.push({ actual: { codes, status: invalid.child.status }, expected: "renderer_side_effect_capability", name: "renderer_side_effect", ok: invalid.child.status !== 0 && codes.includes("renderer_side_effect_capability") });
27
- } finally {
28
- fs.rmSync(tempRoot, { force: true, recursive: true });
29
- }
30
-
31
- const failures = cases.filter((testCase) => !testCase.ok).map((testCase) => `missing_semantic:${testCase.name}:${testCase.expected}`);
32
- const result = { failures, ok: failures.length === 0, results: cases };
33
- process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
34
- if (!result.ok) process.exitCode = 1;
@@ -1,129 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { spawnSync } from "node:child_process";
4
- import path from "node:path";
5
- import { fileURLToPath } from "node:url";
6
- import { agentNativeFixture } from "./agent-native/fixture.mjs";
7
-
8
- const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
9
- const cli = path.join(repositoryRoot, "scripts", "sg.mjs");
10
- const profileRef = "sg:profile/editorial-reference-profile";
11
- const versionRef = agentNativeFixture.records.find(({ stable_ref }) => stable_ref === profileRef)?.version_id;
12
-
13
- const successCases = [
14
- { command: "discover", baseArgs: ["discover"] },
15
- { command: "resolve", baseArgs: ["resolve", profileRef] },
16
- { command: "resolve", baseArgs: ["resolve", versionRef], name: "resolve_version_id" },
17
- { command: "claims", baseArgs: ["claims", profileRef] },
18
- { command: "context", baseArgs: ["context", profileRef] },
19
- { command: "ops", baseArgs: ["ops"] },
20
- ];
21
-
22
- const failureCases = [
23
- { args: ["--format", "json"], code: "argument_value_required", name: "missing_command" },
24
- { args: ["resolve", "--format", "json"], code: "argument_value_required", name: "resolve_missing_stable_ref" },
25
- { args: ["claims", "--format", "json"], code: "argument_value_required", name: "claims_missing_stable_ref" },
26
- { args: ["resolve", "not-a-stable-ref", "--format", "json"], code: "stable_ref_malformed", name: "malformed_stable_ref" },
27
- { args: ["resolve", "sg:profile/unknown-profile", "--format", "json"], code: "stable_ref_unknown", name: "unknown_stable_ref" },
28
- { args: ["unknown-command", "--format", "json"], code: "command_unknown", name: "unknown_command" },
29
- { args: ["discover", "--unknown", "--format", "json"], code: "argument_unknown", name: "unknown_option" },
30
- { args: ["--format", "json", "discover", "--format"], code: "argument_value_required", name: "format_missing_value" },
31
- { args: ["--format", "json", "discover", "--format", "yaml"], code: "format_unsupported", name: "unsupported_format" },
32
- ];
33
-
34
- function run(args) {
35
- return spawnSync(process.execPath, [cli, ...args], {
36
- cwd: repositoryRoot,
37
- encoding: "utf8",
38
- });
39
- }
40
-
41
- function parseJson(child) {
42
- if (typeof child.stdout !== "string" || child.stdout.length === 0) return null;
43
- try {
44
- return JSON.parse(child.stdout);
45
- } catch {
46
- return null;
47
- }
48
- }
49
-
50
- function summarize(child, report) {
51
- return {
52
- report,
53
- signal: child.signal,
54
- status: child.status,
55
- stderr: child.stderr,
56
- stdout: child.stdout,
57
- };
58
- }
59
-
60
- function hasSuccessContract(child, report, command) {
61
- return child.status === 0
62
- && child.signal === null
63
- && child.stderr.length === 0
64
- && report !== null
65
- && report.ok === true
66
- && report.operation === command
67
- && report.result !== null
68
- && typeof report.result === "object";
69
- }
70
-
71
- function formatVariants(baseArgs) {
72
- const command = baseArgs[0];
73
- const operands = baseArgs.slice(1);
74
- return [
75
- [...baseArgs, "--format", "json"],
76
- ["--format", "json", ...baseArgs],
77
- [command, "--format", "json", ...operands],
78
- ];
79
- }
80
-
81
- function runSuccessCase(testCase) {
82
- const variants = formatVariants(testCase.baseArgs);
83
- const runs = variants.map((args) => {
84
- const child = run(args);
85
- return { args, child, report: parseJson(child) };
86
- });
87
- const reference = runs[0];
88
- const equivalent = runs.every(({ child, report }) => (
89
- hasSuccessContract(child, report, testCase.command)
90
- && child.stdout === reference.child.stdout
91
- ));
92
- const repeated = run(testCase.baseArgs.concat(["--format", "json"]));
93
- const repeatedReport = parseJson(repeated);
94
- const deterministic = hasSuccessContract(repeated, repeatedReport, testCase.command)
95
- && repeated.stdout === reference.child.stdout;
96
- return {
97
- actual: runs.map(({ args, child, report }) => ({ args, ...summarize(child, report) })),
98
- expected: "all --format json positions produce one stdout-only success JSON document with identical bytes",
99
- name: `${testCase.name ?? testCase.command}_format_order_and_stdout_contract`,
100
- ok: equivalent && deterministic,
101
- };
102
- }
103
-
104
- function runFailureCase(testCase) {
105
- const child = run(testCase.args);
106
- const report = parseJson(child);
107
- const codes = Array.isArray(report?.failures)
108
- ? report.failures.map((failure) => failure?.code)
109
- : [];
110
- return {
111
- actual: { codes, ...summarize(child, report) },
112
- expected: `nonzero stdout-only JSON failure containing stable code ${testCase.code}`,
113
- name: testCase.name,
114
- ok: child.status !== 0
115
- && child.signal === null
116
- && child.stderr.length === 0
117
- && report?.ok === false
118
- && codes.length > 0
119
- && codes.includes(testCase.code),
120
- };
121
- }
122
-
123
- const results = [
124
- ...successCases.map(runSuccessCase),
125
- ...failureCases.map(runFailureCase),
126
- ];
127
- const report = { ok: results.every((result) => result.ok), results };
128
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
129
- process.exitCode = report.ok ? 0 : 1;