@design-parity/action 0.1.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 (66) hide show
  1. package/README.md +109 -0
  2. package/dist/baseline.d.ts +48 -0
  3. package/dist/baseline.d.ts.map +1 -0
  4. package/dist/baseline.js +126 -0
  5. package/dist/baseline.js.map +1 -0
  6. package/dist/candidate.d.ts +48 -0
  7. package/dist/candidate.d.ts.map +1 -0
  8. package/dist/candidate.js +109 -0
  9. package/dist/candidate.js.map +1 -0
  10. package/dist/cli/action.d.ts +3 -0
  11. package/dist/cli/action.d.ts.map +1 -0
  12. package/dist/cli/action.js +222 -0
  13. package/dist/cli/action.js.map +1 -0
  14. package/dist/cli/run.d.ts +3 -0
  15. package/dist/cli/run.d.ts.map +1 -0
  16. package/dist/cli/run.js +123 -0
  17. package/dist/cli/run.js.map +1 -0
  18. package/dist/config.d.ts +23 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +46 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/github/changed-components.d.ts +15 -0
  23. package/dist/github/changed-components.d.ts.map +1 -0
  24. package/dist/github/changed-components.js +18 -0
  25. package/dist/github/changed-components.js.map +1 -0
  26. package/dist/github/conclusion.d.ts +16 -0
  27. package/dist/github/conclusion.d.ts.map +1 -0
  28. package/dist/github/conclusion.js +17 -0
  29. package/dist/github/conclusion.js.map +1 -0
  30. package/dist/github/publish.d.ts +50 -0
  31. package/dist/github/publish.d.ts.map +1 -0
  32. package/dist/github/publish.js +91 -0
  33. package/dist/github/publish.js.map +1 -0
  34. package/dist/github/rest.d.ts +29 -0
  35. package/dist/github/rest.d.ts.map +1 -0
  36. package/dist/github/rest.js +64 -0
  37. package/dist/github/rest.js.map +1 -0
  38. package/dist/github/surface.d.ts +17 -0
  39. package/dist/github/surface.d.ts.map +1 -0
  40. package/dist/github/surface.js +21 -0
  41. package/dist/github/surface.js.map +1 -0
  42. package/dist/index.d.ts +33 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +23 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/mode.d.ts +35 -0
  47. package/dist/mode.d.ts.map +1 -0
  48. package/dist/mode.js +25 -0
  49. package/dist/mode.js.map +1 -0
  50. package/dist/orchestrate.d.ts +80 -0
  51. package/dist/orchestrate.d.ts.map +1 -0
  52. package/dist/orchestrate.js +100 -0
  53. package/dist/orchestrate.js.map +1 -0
  54. package/dist/pushback.d.ts +81 -0
  55. package/dist/pushback.d.ts.map +1 -0
  56. package/dist/pushback.js +106 -0
  57. package/dist/pushback.js.map +1 -0
  58. package/dist/registry.d.ts +24 -0
  59. package/dist/registry.d.ts.map +1 -0
  60. package/dist/registry.js +14 -0
  61. package/dist/registry.js.map +1 -0
  62. package/dist/report.d.ts +29 -0
  63. package/dist/report.d.ts.map +1 -0
  64. package/dist/report.js +72 -0
  65. package/dist/report.js.map +1 -0
  66. package/package.json +40 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Code-to-Canvas push-back (issue #9) — the `code-led`, Figma-only stretch.
3
+ *
4
+ * After a parity run, optionally push each candidate render back into the
5
+ * design tool so the design file reflects what shipped. This is **gated** three
6
+ * ways (docs/PRINCIPLES.md, Principle 5):
7
+ *
8
+ * 1. an explicit opt-in flag, **and**
9
+ * 2. the resolved direction is `code-led` (in `design-led` the design stays
10
+ * canonical and code is never pushed back), **and**
11
+ * 3. the component's `source` is `figma`.
12
+ *
13
+ * Anything short of all three is a **no-op with a clear log line**. The actual
14
+ * write goes through an injected {@link CanvasWriter}; with no writer configured
15
+ * the run also no-ops (the Figma REST API is read-only, so a real writer needs a
16
+ * companion plugin / Dev Mode bridge). This module is otherwise pure: it makes
17
+ * no network or model calls itself.
18
+ */
19
+ import type { AdapterContext, CanvasWriteResult, CanvasWriter, ResolvedDirection } from "@design-parity/core";
20
+ import type { ParityReport } from "./orchestrate.js";
21
+ /** Whether a run, as a whole, is eligible to push candidates back. */
22
+ export interface PushBackGate {
23
+ eligible: boolean;
24
+ /** A clear, human-readable reason when not eligible (the no-op log line). */
25
+ reason?: string;
26
+ }
27
+ /**
28
+ * The overall gate: push-back runs only when explicitly opted in **and** the
29
+ * direction is `code-led`. Pure and deterministic — the per-component
30
+ * `source === "figma"` check happens during {@link pushBack}.
31
+ */
32
+ export declare function decidePushBack(input: {
33
+ enabled: boolean;
34
+ direction: ResolvedDirection;
35
+ }): PushBackGate;
36
+ export interface PushedImage {
37
+ /** `state/theme/size` key of the pushed image. */
38
+ key: string;
39
+ result: CanvasWriteResult;
40
+ }
41
+ export interface PushBackComponent {
42
+ code: string;
43
+ pushed: PushedImage[];
44
+ }
45
+ export interface PushBackSkip {
46
+ code: string;
47
+ reason: string;
48
+ }
49
+ export interface PushBackError {
50
+ code: string;
51
+ message: string;
52
+ }
53
+ /** The outcome of a push-back pass over a {@link ParityReport}. */
54
+ export interface PushBackReport {
55
+ /** True only when the gate let the run write at all (flag on, `code-led`, a writer). */
56
+ attempted: boolean;
57
+ /** Why the run did not attempt any write (the overall no-op log line). */
58
+ reason?: string;
59
+ pushed: PushBackComponent[];
60
+ skipped: PushBackSkip[];
61
+ /** Per-component write failures (fail-soft: never thrown). */
62
+ errors: PushBackError[];
63
+ }
64
+ export interface PushBackOptions {
65
+ report: ParityReport;
66
+ /** The explicit opt-in flag — push-back only runs when this is `true`. */
67
+ enabled: boolean;
68
+ /** Writer for the design tool; absent means no-op (no transport configured). */
69
+ writer?: CanvasWriter;
70
+ /** Context the writer resolves image paths / credentials against. */
71
+ ctx: AdapterContext;
72
+ /** Sink for the clear log lines the acceptance criteria call for. */
73
+ log?: (message: string) => void;
74
+ }
75
+ /**
76
+ * Run Code-to-Canvas push-back for a completed parity report. Honors the
77
+ * three-way gate, fails soft per component, and emits a clear log line in every
78
+ * branch (no-op or not). Never throws.
79
+ */
80
+ export declare function pushBack(opts: PushBackOptions): Promise<PushBackReport>;
81
+ //# sourceMappingURL=pushback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pushback.d.ts","sourceRoot":"","sources":["../src/pushback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EACV,cAAc,EAEd,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEtE,sEAAsE;AACtE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,iBAAiB,CAAC;CAC9B,GAAG,YAAY,CAcf;AA2CD,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,wFAAwF;IACxF,SAAS,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,8DAA8D;IAC9D,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,YAAY,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,qEAAqE;IACrE,GAAG,EAAE,cAAc,CAAC;IACpB,qEAAqE;IACrE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAkD7E"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The overall gate: push-back runs only when explicitly opted in **and** the
3
+ * direction is `code-led`. Pure and deterministic — the per-component
4
+ * `source === "figma"` check happens during {@link pushBack}.
5
+ */
6
+ export function decidePushBack(input) {
7
+ if (!input.enabled) {
8
+ return {
9
+ eligible: false,
10
+ reason: "Code-to-Canvas push-back is off (opt-in flag not set).",
11
+ };
12
+ }
13
+ if (input.direction !== "code-led") {
14
+ return {
15
+ eligible: false,
16
+ reason: `Code-to-Canvas push-back skipped: direction is '${input.direction}', not 'code-led' (design stays canonical).`,
17
+ };
18
+ }
19
+ return { eligible: true };
20
+ }
21
+ /** A short, stable key for one candidate image (state/theme/size). */
22
+ function imageKey(target) {
23
+ const { state, theme, size } = target.image;
24
+ return `${state}/${theme ?? "-"}/${size ?? "-"}`;
25
+ }
26
+ /**
27
+ * The candidate images to push back for one component, or `[]` with the reason
28
+ * it was skipped. A component is eligible only when it diffed cleanly against a
29
+ * matching-source reference and carries a candidate render.
30
+ */
31
+ function targetsFor(result, source) {
32
+ if (result.source !== source) {
33
+ return {
34
+ targets: [],
35
+ reason: `source is '${result.source ?? "unknown"}', not '${source}' — nothing to push back`,
36
+ };
37
+ }
38
+ if (result.status !== "ok") {
39
+ return { targets: [], reason: `component was ${result.status}, no candidate to push back` };
40
+ }
41
+ const ref = result.reference?.ref;
42
+ if (!ref) {
43
+ return { targets: [], reason: "no resolved design reference to write to" };
44
+ }
45
+ const images = result.candidate?.images ?? [];
46
+ if (images.length === 0) {
47
+ return { targets: [], reason: "no candidate render to push back" };
48
+ }
49
+ const targets = images.map((image) => ({
50
+ componentId: result.code,
51
+ source,
52
+ ref,
53
+ image,
54
+ }));
55
+ return { targets };
56
+ }
57
+ /**
58
+ * Run Code-to-Canvas push-back for a completed parity report. Honors the
59
+ * three-way gate, fails soft per component, and emits a clear log line in every
60
+ * branch (no-op or not). Never throws.
61
+ */
62
+ export async function pushBack(opts) {
63
+ const log = opts.log ?? (() => { });
64
+ const gate = decidePushBack({
65
+ enabled: opts.enabled,
66
+ direction: opts.report.direction,
67
+ });
68
+ if (!gate.eligible) {
69
+ log(`design-parity: ${gate.reason}`);
70
+ return { attempted: false, reason: gate.reason, pushed: [], skipped: [], errors: [] };
71
+ }
72
+ if (!opts.writer) {
73
+ const reason = "Code-to-Canvas push-back is enabled (code-led), but no canvas writer is " +
74
+ "configured — set up a Figma bridge endpoint to push candidates back.";
75
+ log(`design-parity: ${reason}`);
76
+ return { attempted: false, reason, pushed: [], skipped: [], errors: [] };
77
+ }
78
+ const writer = opts.writer;
79
+ const pushed = [];
80
+ const skipped = [];
81
+ const errors = [];
82
+ for (const result of opts.report.results) {
83
+ const { targets, reason } = targetsFor(result, writer.source);
84
+ if (targets.length === 0) {
85
+ skipped.push({ code: result.code, reason: reason ?? "not eligible" });
86
+ continue;
87
+ }
88
+ const images = [];
89
+ for (const target of targets) {
90
+ try {
91
+ const written = await writer.write(target, opts.ctx);
92
+ images.push({ key: imageKey(target), result: written });
93
+ }
94
+ catch (err) {
95
+ // Fail soft: one bad write must not abort the rest or throw.
96
+ errors.push({ code: result.code, message: err.message });
97
+ }
98
+ }
99
+ if (images.length > 0)
100
+ pushed.push({ code: result.code, pushed: images });
101
+ }
102
+ log(`design-parity: Code-to-Canvas pushed ${pushed.length} component(s) back to ` +
103
+ `'${writer.source}' (${skipped.length} skipped, ${errors.length} error(s)).`);
104
+ return { attempted: true, pushed, skipped, errors };
105
+ }
106
+ //# sourceMappingURL=pushback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pushback.js","sourceRoot":"","sources":["../src/pushback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The `source → adapter` registry.
3
+ *
4
+ * Each adapter only declares a const `source`; nothing maps a {@link DesignSource}
5
+ * to a concrete {@link ReferenceAdapter}. That map can't live in `core` (core must
6
+ * not depend on adapters), so it lives here — the one place that imports all the
7
+ * drivers. Per-adapter options are injectable so tests and the CLI can supply
8
+ * credentials, output dirs, or fakes.
9
+ */
10
+ import type { DesignSource, ReferenceAdapter } from "@design-parity/core";
11
+ import { createFigmaAdapter } from "@design-parity/adapter-figma";
12
+ import { createStitchAdapter } from "@design-parity/adapter-stitch";
13
+ import { ClaudeDesignAdapter } from "@design-parity/adapter-claude-design";
14
+ import { createBundleAdapter } from "@design-parity/adapter-bundle";
15
+ export type AdapterRegistry = Record<DesignSource, ReferenceAdapter>;
16
+ export interface RegistryOptions {
17
+ figma?: Parameters<typeof createFigmaAdapter>[0];
18
+ stitch?: Parameters<typeof createStitchAdapter>[0];
19
+ claudeDesign?: ConstructorParameters<typeof ClaudeDesignAdapter>[0];
20
+ bundle?: Parameters<typeof createBundleAdapter>[0];
21
+ }
22
+ /** Build the default registry wiring all reference drivers. */
23
+ export declare function createAdapterRegistry(opts?: RegistryOptions): AdapterRegistry;
24
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,qBAAqB,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;CACpD;AAED,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,eAAoB,GAAG,eAAe,CAOjF"}
@@ -0,0 +1,14 @@
1
+ import { createFigmaAdapter } from "@design-parity/adapter-figma";
2
+ import { createStitchAdapter } from "@design-parity/adapter-stitch";
3
+ import { ClaudeDesignAdapter } from "@design-parity/adapter-claude-design";
4
+ import { createBundleAdapter } from "@design-parity/adapter-bundle";
5
+ /** Build the default registry wiring all reference drivers. */
6
+ export function createAdapterRegistry(opts = {}) {
7
+ return {
8
+ figma: createFigmaAdapter(opts.figma),
9
+ stitch: createStitchAdapter(opts.stitch),
10
+ "claude-design": new ClaudeDesignAdapter(opts.claudeDesign),
11
+ bundle: createBundleAdapter(opts.bundle),
12
+ };
13
+ }
14
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAWpE,+DAA+D;AAC/D,MAAM,UAAU,qBAAqB,CAAC,OAAwB,EAAE;IAC9D,OAAO;QACL,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC;QACrC,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;QACxC,eAAe,EAAE,IAAI,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC;QAC3D,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;KACzC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Render a {@link ParityReport} as the single markdown comment the bot posts on
3
+ * a PR (and the CLI prints). a11y + i18n lead each component's section (that
4
+ * ordering is owned by the diff summary); this layer adds the overall verdict,
5
+ * the direction-driven blocking note, and the per-component roll-up.
6
+ */
7
+ import type { ParityReport } from "./orchestrate.js";
8
+ /** Stable marker so the GitHub surface can find and update its own comment. */
9
+ export declare const REPORT_MARKER = "<!-- design-parity-report -->";
10
+ /**
11
+ * The comment posted when a PR runs against a repo that has **no committed
12
+ * parity setup** — no (or an empty) `design-map.json`. The unattended Action
13
+ * enforces committed deterministic artifacts; it never generates them at run
14
+ * time (Principle 1), so instead of silently guessing it points the user at the
15
+ * interactive bootstrap (issue #11 / the `design-parity-bootstrap` CLI).
16
+ *
17
+ * Carries the same {@link REPORT_MARKER} as a verdict comment, so it updates in
18
+ * place and is replaced by a real verdict on the first run after setup lands.
19
+ */
20
+ export declare function renderBootstrapNotice(): string;
21
+ /**
22
+ * The non-blocking Compose Multiplatform promotion shown on Android-only repos
23
+ * (docs/PRINCIPLES.md, Principle 6). Surfaced only when the committed
24
+ * `cmpCapable` flag is `false`; phrased for the PR comment (the bootstrap output
25
+ * has its own, longer wording). Advisory — it never changes the verdict.
26
+ */
27
+ export declare const CMP_PROMOTION: string;
28
+ export declare function renderReport(report: ParityReport): string;
29
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIrD,+EAA+E;AAC/E,eAAO,MAAM,aAAa,kCAAkC,CAAC;AAE7D;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAgB9C;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAK6C,CAAC;AAExE,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAkDzD"}
package/dist/report.js ADDED
@@ -0,0 +1,72 @@
1
+ const STATUS_ICON = { pass: "✅", warn: "⚠️", fail: "❌" };
2
+ /** Stable marker so the GitHub surface can find and update its own comment. */
3
+ export const REPORT_MARKER = "<!-- design-parity-report -->";
4
+ /**
5
+ * The comment posted when a PR runs against a repo that has **no committed
6
+ * parity setup** — no (or an empty) `design-map.json`. The unattended Action
7
+ * enforces committed deterministic artifacts; it never generates them at run
8
+ * time (Principle 1), so instead of silently guessing it points the user at the
9
+ * interactive bootstrap (issue #11 / the `design-parity-bootstrap` CLI).
10
+ *
11
+ * Carries the same {@link REPORT_MARKER} as a verdict comment, so it updates in
12
+ * place and is replaced by a real verdict on the first run after setup lands.
13
+ */
14
+ export function renderBootstrapNotice() {
15
+ return [
16
+ REPORT_MARKER,
17
+ "",
18
+ "# Design parity",
19
+ "",
20
+ "ℹ️ **Not set up yet** — this repo has no committed `design-map.json`, so there's nothing to check parity against (no PR is blocked).",
21
+ "",
22
+ "design-parity runs unattended on committed, deterministic artifacts and never guesses your design ↔ code mapping at run time. To set it up, run the interactive bootstrap once and commit what it generates:",
23
+ "",
24
+ "```sh",
25
+ "npx design-parity-bootstrap",
26
+ "```",
27
+ "",
28
+ "It detects your design-system maturity and seeds a starter `design-map.json`, check config, and parity direction (`.design-parity.json`). See [issue #11](https://github.com/yschimke/design-parity/issues/11) for the setup flow.",
29
+ ].join("\n");
30
+ }
31
+ /**
32
+ * The non-blocking Compose Multiplatform promotion shown on Android-only repos
33
+ * (docs/PRINCIPLES.md, Principle 6). Surfaced only when the committed
34
+ * `cmpCapable` flag is `false`; phrased for the PR comment (the bootstrap output
35
+ * has its own, longer wording). Advisory — it never changes the verdict.
36
+ */
37
+ export const CMP_PROMOTION = "💡 **Tip — Compose Multiplatform.** This project looks Android-only " +
38
+ "(Jetpack Compose). On Compose Multiplatform it could run parity faster: the " +
39
+ "candidate renders on the JVM/desktop with **no Android emulator**, which is " +
40
+ "cheaper and easier to run unattended. Advisory only — plain Jetpack Compose " +
41
+ "stays fully supported. See [adopting-cmp.md](docs/adopting-cmp.md).";
42
+ export function renderReport(report) {
43
+ const lines = [REPORT_MARKER];
44
+ const headline = report.blocked
45
+ ? `${STATUS_ICON.fail} **Parity check failed** — blocking (\`${report.direction}\`)`
46
+ : `${STATUS_ICON[report.status]} **Parity ${report.status}** (\`${report.direction}\`${report.status === "fail" ? ", advisory" : ""})`;
47
+ lines.push("", `# Design parity`, "", headline);
48
+ const checked = report.results.filter((r) => r.verdict);
49
+ if (checked.length === 0) {
50
+ lines.push("", "_No components were checked._");
51
+ }
52
+ for (const r of report.results) {
53
+ if (r.summary) {
54
+ lines.push("", "---", "", r.summary);
55
+ }
56
+ else if (r.status === "skipped") {
57
+ lines.push("", "---", "", `### \`${r.code}\` — skipped`, `_${r.note}._`);
58
+ }
59
+ else if (r.status === "error") {
60
+ lines.push("", "---", "", `### \`${r.code}\` — ⚠️ not checked`, `_Adapter/diff error (failed soft): ${r.note}._`);
61
+ }
62
+ }
63
+ // Promote CMP to Android-only repos (Principle 6) — non-blocking, never a gate.
64
+ if (report.cmpCapable === false) {
65
+ lines.push("", "---", "", CMP_PROMOTION);
66
+ }
67
+ if (report.warnings.length > 0) {
68
+ lines.push("", "---", "", "<details><summary>Warnings</summary>", "", ...report.warnings.map((w) => `- ${w}`), "", "</details>");
69
+ }
70
+ return lines.join("\n");
71
+ }
72
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@design-parity/action",
3
+ "version": "0.1.0",
4
+ "description": "Integration layer: wires resolver, adapters, candidate, checks, diff, and policy into a parity run, and surfaces the verdict (CLI now; GitHub Action surface to follow).",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": "./dist/index.js",
11
+ "./run": "./dist/cli/run.js"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc --build",
18
+ "test": "vitest run"
19
+ },
20
+ "dependencies": {
21
+ "@design-parity/core": "^0.1.0",
22
+ "@design-parity/resolver": "^0.1.0",
23
+ "@design-parity/policy": "^0.1.0",
24
+ "@design-parity/diff": "^0.1.0",
25
+ "@design-parity/report-html": "^0.1.0",
26
+ "@design-parity/checks": "^0.1.0",
27
+ "@design-parity/candidate": "^0.1.0",
28
+ "@design-parity/adapter-figma": "^0.1.0",
29
+ "@design-parity/adapter-stitch": "^0.1.0",
30
+ "@design-parity/adapter-claude-design": "^0.1.0",
31
+ "@design-parity/adapter-bundle": "^0.1.0"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/yschimke/design-parity.git",
36
+ "directory": "packages/action"
37
+ },
38
+ "homepage": "https://github.com/yschimke/design-parity/tree/main/packages/action#readme",
39
+ "bugs": "https://github.com/yschimke/design-parity/issues"
40
+ }