@12ui/design 0.2.55 → 0.2.57
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/SKILL.md +1 -1
- package/dist/branch-client.d.ts +2 -0
- package/dist/branch-client.d.ts.map +1 -1
- package/dist/branch-client.js +1 -0
- package/dist/branch-client.js.map +1 -1
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +2 -0
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-conversion-derivation.d.ts +2 -1
- package/dist/cli-conversion-derivation.d.ts.map +1 -1
- package/dist/cli-conversion-derivation.js +9 -1
- package/dist/cli-conversion-derivation.js.map +1 -1
- package/dist/cli-convert-command.d.ts.map +1 -1
- package/dist/cli-convert-command.js +111 -16
- package/dist/cli-convert-command.js.map +1 -1
- package/dist/cli-corpus-command.d.ts.map +1 -1
- package/dist/cli-corpus-command.js +5 -2
- package/dist/cli-corpus-command.js.map +1 -1
- package/dist/cli-corpus-evidence.d.ts.map +1 -1
- package/dist/cli-corpus-evidence.js +2 -1
- package/dist/cli-corpus-evidence.js.map +1 -1
- package/dist/cli-corpus-reference-downloads.d.ts +1 -0
- package/dist/cli-corpus-reference-downloads.d.ts.map +1 -1
- package/dist/cli-corpus-reference-downloads.js +13 -3
- package/dist/cli-corpus-reference-downloads.js.map +1 -1
- package/dist/cli-corpus-types.d.ts +2 -0
- package/dist/cli-corpus-types.d.ts.map +1 -1
- package/dist/cli-draft-command.d.ts +11 -0
- package/dist/cli-draft-command.d.ts.map +1 -1
- package/dist/cli-draft-command.js +10 -1
- package/dist/cli-draft-command.js.map +1 -1
- package/dist/cli-help/design.d.ts +2 -2
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +12 -2
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +2 -2
- package/dist/cli-improve-command.d.ts.map +1 -1
- package/dist/cli-improve-command.js +317 -70
- package/dist/cli-improve-command.js.map +1 -1
- package/dist/cli-next-command.d.ts.map +1 -1
- package/dist/cli-next-command.js +44 -4
- package/dist/cli-next-command.js.map +1 -1
- package/dist/cli-usage.js +2 -2
- package/dist/concept-input.d.ts +21 -0
- package/dist/concept-input.d.ts.map +1 -1
- package/dist/concept-input.js +32 -10
- package/dist/concept-input.js.map +1 -1
- package/dist/conversion-client.d.ts +39 -1
- package/dist/conversion-client.d.ts.map +1 -1
- package/dist/conversion-client.js +205 -3
- package/dist/conversion-client.js.map +1 -1
- package/dist/corpus-client.d.ts +7 -1
- package/dist/corpus-client.d.ts.map +1 -1
- package/dist/corpus-client.js +6 -2
- package/dist/corpus-client.js.map +1 -1
- package/dist/corpus-reference-download-retry.d.ts +68 -0
- package/dist/corpus-reference-download-retry.d.ts.map +1 -0
- package/dist/corpus-reference-download-retry.js +123 -0
- package/dist/corpus-reference-download-retry.js.map +1 -0
- package/dist/corpus-request-error.d.ts +17 -0
- package/dist/corpus-request-error.d.ts.map +1 -0
- package/dist/corpus-request-error.js +21 -0
- package/dist/corpus-request-error.js.map +1 -0
- package/dist/draft-run.d.ts +9 -0
- package/dist/draft-run.d.ts.map +1 -1
- package/dist/draft-run.js +22 -5
- package/dist/draft-run.js.map +1 -1
- package/dist/draft-workspace.d.ts +2 -1
- package/dist/draft-workspace.d.ts.map +1 -1
- package/dist/draft-workspace.js.map +1 -1
- package/dist/hosted-draft-identity.d.ts +1 -0
- package/dist/hosted-draft-identity.d.ts.map +1 -1
- package/dist/hosted-draft-identity.js +1 -0
- package/dist/hosted-draft-identity.js.map +1 -1
- package/dist/improve-added-specs.d.ts +9 -0
- package/dist/improve-added-specs.d.ts.map +1 -1
- package/dist/improve-added-specs.js +28 -7
- package/dist/improve-added-specs.js.map +1 -1
- package/dist/improve-bootstrap-secret.d.ts +35 -0
- package/dist/improve-bootstrap-secret.d.ts.map +1 -0
- package/dist/improve-bootstrap-secret.js +61 -0
- package/dist/improve-bootstrap-secret.js.map +1 -0
- package/dist/improve-capture-redirect.d.ts +46 -0
- package/dist/improve-capture-redirect.d.ts.map +1 -0
- package/dist/improve-capture-redirect.js +68 -0
- package/dist/improve-capture-redirect.js.map +1 -0
- package/dist/improve-concept.d.ts +14 -1
- package/dist/improve-concept.d.ts.map +1 -1
- package/dist/improve-concept.js +29 -8
- package/dist/improve-concept.js.map +1 -1
- package/dist/improve-conversion-attempts.d.ts +96 -0
- package/dist/improve-conversion-attempts.d.ts.map +1 -0
- package/dist/improve-conversion-attempts.js +93 -0
- package/dist/improve-conversion-attempts.js.map +1 -0
- package/dist/improve-conversion-stage.d.ts +14 -0
- package/dist/improve-conversion-stage.d.ts.map +1 -1
- package/dist/improve-conversion-stage.js +254 -70
- package/dist/improve-conversion-stage.js.map +1 -1
- package/dist/improve-convert-progress.d.ts +36 -0
- package/dist/improve-convert-progress.d.ts.map +1 -0
- package/dist/improve-convert-progress.js +43 -0
- package/dist/improve-convert-progress.js.map +1 -0
- package/dist/improve-convert-resilience.d.ts +116 -0
- package/dist/improve-convert-resilience.d.ts.map +1 -1
- package/dist/improve-convert-resilience.js +158 -1
- package/dist/improve-convert-resilience.js.map +1 -1
- package/dist/improve-delivery-stages.d.ts.map +1 -1
- package/dist/improve-delivery-stages.js +5 -0
- package/dist/improve-delivery-stages.js.map +1 -1
- package/dist/improve-dom-diff.d.ts +2 -0
- package/dist/improve-dom-diff.d.ts.map +1 -1
- package/dist/improve-dom-diff.js +7 -0
- package/dist/improve-dom-diff.js.map +1 -1
- package/dist/improve-dom-gate.d.ts +7 -0
- package/dist/improve-dom-gate.d.ts.map +1 -1
- package/dist/improve-dom-gate.js +13 -0
- package/dist/improve-dom-gate.js.map +1 -1
- package/dist/improve-generation-stages.d.ts +3 -0
- package/dist/improve-generation-stages.d.ts.map +1 -1
- package/dist/improve-generation-stages.js +56 -10
- package/dist/improve-generation-stages.js.map +1 -1
- package/dist/improve-icon-svg.d.ts +47 -0
- package/dist/improve-icon-svg.d.ts.map +1 -0
- package/dist/improve-icon-svg.js +83 -0
- package/dist/improve-icon-svg.js.map +1 -0
- package/dist/improve-kit-assets.d.ts +129 -0
- package/dist/improve-kit-assets.d.ts.map +1 -0
- package/dist/improve-kit-assets.js +333 -0
- package/dist/improve-kit-assets.js.map +1 -0
- package/dist/improve-kit-ignore.d.ts +32 -0
- package/dist/improve-kit-ignore.d.ts.map +1 -0
- package/dist/improve-kit-ignore.js +111 -0
- package/dist/improve-kit-ignore.js.map +1 -0
- package/dist/improve-kit-readme.d.ts +11 -2
- package/dist/improve-kit-readme.d.ts.map +1 -1
- package/dist/improve-kit-readme.js +282 -26
- package/dist/improve-kit-readme.js.map +1 -1
- package/dist/improve-kit-stall.d.ts +113 -0
- package/dist/improve-kit-stall.d.ts.map +1 -0
- package/dist/improve-kit-stall.js +311 -0
- package/dist/improve-kit-stall.js.map +1 -0
- package/dist/improve-kit-status.d.ts +105 -0
- package/dist/improve-kit-status.d.ts.map +1 -0
- package/dist/improve-kit-status.js +215 -0
- package/dist/improve-kit-status.js.map +1 -0
- package/dist/improve-options.d.ts +16 -1
- package/dist/improve-options.d.ts.map +1 -1
- package/dist/improve-options.js +65 -15
- package/dist/improve-options.js.map +1 -1
- package/dist/improve-plan-annotated-render.d.ts +45 -0
- package/dist/improve-plan-annotated-render.d.ts.map +1 -0
- package/dist/improve-plan-annotated-render.js +196 -0
- package/dist/improve-plan-annotated-render.js.map +1 -0
- package/dist/improve-plan-annotator.d.ts +7 -1
- package/dist/improve-plan-annotator.d.ts.map +1 -1
- package/dist/improve-plan-annotator.js +22 -45
- package/dist/improve-plan-annotator.js.map +1 -1
- package/dist/improve-raster-layers-section.d.ts +21 -0
- package/dist/improve-raster-layers-section.d.ts.map +1 -0
- package/dist/improve-raster-layers-section.js +45 -0
- package/dist/improve-raster-layers-section.js.map +1 -0
- package/dist/improve-reset.d.ts +122 -0
- package/dist/improve-reset.d.ts.map +1 -0
- package/dist/improve-reset.js +141 -0
- package/dist/improve-reset.js.map +1 -0
- package/dist/improve-run-summary.d.ts +35 -0
- package/dist/improve-run-summary.d.ts.map +1 -0
- package/dist/improve-run-summary.js +180 -0
- package/dist/improve-run-summary.js.map +1 -0
- package/dist/improve-stage-shared.d.ts +44 -1
- package/dist/improve-stage-shared.d.ts.map +1 -1
- package/dist/improve-stage-shared.js +80 -3
- package/dist/improve-stage-shared.js.map +1 -1
- package/dist/improve-stop-handler.d.ts +73 -0
- package/dist/improve-stop-handler.d.ts.map +1 -0
- package/dist/improve-stop-handler.js +126 -0
- package/dist/improve-stop-handler.js.map +1 -0
- package/dist/improve-terminal-event.d.ts +118 -0
- package/dist/improve-terminal-event.d.ts.map +1 -0
- package/dist/improve-terminal-event.js +87 -0
- package/dist/improve-terminal-event.js.map +1 -0
- package/dist/improve-token-patch.d.ts +2 -0
- package/dist/improve-token-patch.d.ts.map +1 -1
- package/dist/improve-token-patch.js +23 -5
- package/dist/improve-token-patch.js.map +1 -1
- package/dist/improve-workspace.d.ts +94 -2
- package/dist/improve-workspace.d.ts.map +1 -1
- package/dist/improve-workspace.js +19 -1
- package/dist/improve-workspace.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +143 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/mcp-tool-definitions.js +1 -1
- package/dist/mcp-tool-definitions.js.map +1 -1
- package/dist/mcp-tool-handler.d.ts.map +1 -1
- package/dist/mcp-tool-handler.js +3 -0
- package/dist/mcp-tool-handler.js.map +1 -1
- package/dist/redesign-capture.d.ts +17 -0
- package/dist/redesign-capture.d.ts.map +1 -1
- package/dist/redesign-capture.js +55 -3
- package/dist/redesign-capture.js.map +1 -1
- package/dist/responsive-alternative-materializer.d.ts +19 -0
- package/dist/responsive-alternative-materializer.d.ts.map +1 -0
- package/dist/responsive-alternative-materializer.js +76 -0
- package/dist/responsive-alternative-materializer.js.map +1 -0
- package/dist/run-journal-unfinished.d.ts +56 -0
- package/dist/run-journal-unfinished.d.ts.map +1 -0
- package/dist/run-journal-unfinished.js +126 -0
- package/dist/run-journal-unfinished.js.map +1 -0
- package/dist/run-journal.d.ts +25 -1
- package/dist/run-journal.d.ts.map +1 -1
- package/dist/run-journal.js +15 -1
- package/dist/run-journal.js.map +1 -1
- package/open-design.json +2 -2
- package/package.json +1 -1
- package/skills/12ui-design/SKILL.md +9 -1
- package/skills/12ui-design/improve.md +83 -6
- package/skills/12ui-design/inspire.md +1 -1
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { flattenLayerDoc, isRecord } from './improve-layerdoc-diff.js';
|
|
4
|
+
/**
|
|
5
|
+
* What the kit's extracted files ARE, named once.
|
|
6
|
+
*
|
|
7
|
+
* Two overnight lanes threw the design away because nothing in the kit said
|
|
8
|
+
* that `cutout-1-….png` was the hero artwork and `clean-0-….png` was the same
|
|
9
|
+
* backdrop with that artwork removed. One of them hand-drew the ribbon in CSS
|
|
10
|
+
* and crushed the plate under a 64% scrim. The role wording below is the fixed
|
|
11
|
+
* answer, and every renderer — README, plan, stall report — reads it from here
|
|
12
|
+
* so no two surfaces can describe the same file differently.
|
|
13
|
+
*/
|
|
14
|
+
/** A layer covering at least this share of the canvas is the page's imagery, not a detail. */
|
|
15
|
+
export const IMPROVE_HERO_COVERAGE = 0.25;
|
|
16
|
+
/** The most a readability scrim may dim a plate before it is destroying the design. */
|
|
17
|
+
export const IMPROVE_SCRIM_MAX_OPACITY_PCT = 35;
|
|
18
|
+
/**
|
|
19
|
+
* The disposition of every clean plate that is not the page's backdrop.
|
|
20
|
+
*
|
|
21
|
+
* A conversion can emit several: `clean-0` is the backdrop with the artwork
|
|
22
|
+
* removed, `clean-1` is that same backdrop with a further layer removed too.
|
|
23
|
+
* Both used to read `ship`, with no layer and no placement, and a lane shipped
|
|
24
|
+
* `clean-1` — a page whose backdrop had erased the layer nothing else replaced.
|
|
25
|
+
*/
|
|
26
|
+
export const IMPROVE_ALTERNATE_BACKDROP = 'alternate backdrop (only if that layer is omitted)';
|
|
27
|
+
export const IMPROVE_ASSET_ROLE_COPY = {
|
|
28
|
+
'clean-plate': {
|
|
29
|
+
label: 'clean plate',
|
|
30
|
+
instruction: 'the backdrop with the foreground artwork removed.'
|
|
31
|
+
+ ' Use it as the background layer, at full strength.',
|
|
32
|
+
},
|
|
33
|
+
cutout: {
|
|
34
|
+
label: 'cutout',
|
|
35
|
+
instruction: 'the foreground artwork as an alpha PNG. This is the imagery.'
|
|
36
|
+
+ ' Copy it into the repo and place it at its bounds; never redraw it in CSS.',
|
|
37
|
+
},
|
|
38
|
+
'upscaled-plate': {
|
|
39
|
+
label: 'upscaled plate',
|
|
40
|
+
instruction: 'a higher-resolution copy of a plate for crisp rendering;'
|
|
41
|
+
+ ' pick one resolution, do not ship both.',
|
|
42
|
+
},
|
|
43
|
+
'upscaled-region': {
|
|
44
|
+
label: 'upscaled region',
|
|
45
|
+
instruction: 'a higher-resolution copy of a region for crisp rendering;'
|
|
46
|
+
+ ' pick one resolution, do not ship both.',
|
|
47
|
+
},
|
|
48
|
+
'source-crop': {
|
|
49
|
+
label: 'source crop',
|
|
50
|
+
instruction: 'the layer cropped straight out of the source image.'
|
|
51
|
+
+ ' Prefer that layer\'s cutout when one exists.',
|
|
52
|
+
},
|
|
53
|
+
'prepared-source': {
|
|
54
|
+
label: 'prepared source',
|
|
55
|
+
instruction: 'the normalized image the conversion read; the same picture as `winner.png`.',
|
|
56
|
+
},
|
|
57
|
+
design: {
|
|
58
|
+
label: 'winner.png',
|
|
59
|
+
instruction: 'the whole design; the reference for every visual decision.',
|
|
60
|
+
},
|
|
61
|
+
other: {
|
|
62
|
+
label: 'extracted artifact',
|
|
63
|
+
instruction: 'an extracted artifact the conversion produced for a layer.',
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
/** Artifact keys a LayerDoc leaf may carry, best carrier first. */
|
|
67
|
+
const CARRIER_PREFERENCE = ['cutout', 'plate', 'crop', 'region2x', 'plate2x'];
|
|
68
|
+
const ROLE_BY_MANIFEST = {
|
|
69
|
+
'cleaned-plate': 'clean-plate',
|
|
70
|
+
'layer-cutout': 'cutout',
|
|
71
|
+
'layer-crop': 'source-crop',
|
|
72
|
+
'upscaled-plate': 'upscaled-plate',
|
|
73
|
+
'upscaled-region': 'upscaled-region',
|
|
74
|
+
source: 'prepared-source',
|
|
75
|
+
};
|
|
76
|
+
const ROLE_BY_ID_PREFIX = [
|
|
77
|
+
['upscaled-plate-', 'upscaled-plate'],
|
|
78
|
+
['upscaled-region-', 'upscaled-region'],
|
|
79
|
+
['clean-', 'clean-plate'],
|
|
80
|
+
['cutout-', 'cutout'],
|
|
81
|
+
['crop-', 'source-crop'],
|
|
82
|
+
];
|
|
83
|
+
/**
|
|
84
|
+
* What a file is for before the LayerDoc's layers are known. A carrier that no
|
|
85
|
+
* layer claims is still a carrier: only the resolution aids and the two
|
|
86
|
+
* whole-design references are never copied in.
|
|
87
|
+
*/
|
|
88
|
+
const dispositionByRole = (role) => {
|
|
89
|
+
if (role === 'design' || role === 'prepared-source')
|
|
90
|
+
return 'reference only';
|
|
91
|
+
if (role === 'upscaled-plate' || role === 'upscaled-region')
|
|
92
|
+
return 'alternate resolution';
|
|
93
|
+
return 'ship';
|
|
94
|
+
};
|
|
95
|
+
const assetRole = (id, manifestRole) => {
|
|
96
|
+
if (typeof manifestRole === 'string' && ROLE_BY_MANIFEST[manifestRole]) {
|
|
97
|
+
return ROLE_BY_MANIFEST[manifestRole];
|
|
98
|
+
}
|
|
99
|
+
if (id === 'source')
|
|
100
|
+
return 'prepared-source';
|
|
101
|
+
return ROLE_BY_ID_PREFIX.find(([prefix]) => id.startsWith(prefix))?.[1] ?? 'other';
|
|
102
|
+
};
|
|
103
|
+
const boxOfLeaf = (leaf) => (Array.isArray(leaf.box) && leaf.box.length === 4
|
|
104
|
+
&& leaf.box.every((value) => typeof value === 'number' && Number.isFinite(value))
|
|
105
|
+
? leaf.box
|
|
106
|
+
: undefined);
|
|
107
|
+
const layerName = (leaf) => {
|
|
108
|
+
const named = leaf.name;
|
|
109
|
+
const content = typeof leaf.content === 'string' && leaf.content.trim() ? leaf.content.trim() : undefined;
|
|
110
|
+
if (content)
|
|
111
|
+
return content;
|
|
112
|
+
if (typeof named === 'string' && named.trim())
|
|
113
|
+
return named.trim();
|
|
114
|
+
return leaf.kind ?? 'layer';
|
|
115
|
+
};
|
|
116
|
+
const artifactIdsOf = (leaf) => {
|
|
117
|
+
const artifacts = leaf.artifacts;
|
|
118
|
+
if (!isRecord(artifacts))
|
|
119
|
+
return [];
|
|
120
|
+
return Object.entries(artifacts).flatMap(([key, value]) => (isRecord(value) && typeof value.artifactId === 'string'
|
|
121
|
+
? [{ key, id: value.artifactId }]
|
|
122
|
+
: [])).sort((left, right) => {
|
|
123
|
+
const rank = (key) => {
|
|
124
|
+
const index = CARRIER_PREFERENCE.indexOf(key);
|
|
125
|
+
return index < 0 ? CARRIER_PREFERENCE.length : index;
|
|
126
|
+
};
|
|
127
|
+
return rank(left.key) - rank(right.key);
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
export const boundsPct = (box, canvas) => ({
|
|
131
|
+
x: (box[0] / canvas.width) * 100,
|
|
132
|
+
y: (box[1] / canvas.height) * 100,
|
|
133
|
+
width: (box[2] / canvas.width) * 100,
|
|
134
|
+
height: (box[3] / canvas.height) * 100,
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* Which frame the percentages above belong to.
|
|
138
|
+
*
|
|
139
|
+
* A lane read the plan's bounds as pixels of `winner.png` and placed every
|
|
140
|
+
* layer short: the design is its own size (1536x1024 in that run) while the
|
|
141
|
+
* page being rebuilt is the capture frame (1440x900). A percentage is the same
|
|
142
|
+
* number in both frames, so the fix is one line naming the frame — rendered
|
|
143
|
+
* from here so the README and the plan cannot word it differently.
|
|
144
|
+
*/
|
|
145
|
+
export const improveFrameMappingLine = (args) => {
|
|
146
|
+
const size = (value) => (value ? ` (${value.width}\u00d7${value.height})` : '');
|
|
147
|
+
return `Bounds are % of the capture frame${size(args.frame)};`
|
|
148
|
+
+ ` \`winner.png\` is the design at its own size${size(args.design)};`
|
|
149
|
+
+ ' place by percentage, not by pixel.';
|
|
150
|
+
};
|
|
151
|
+
export const formatImproveBounds = (bounds) => (`x ${bounds.x.toFixed(1)}%, y ${bounds.y.toFixed(1)}%,`
|
|
152
|
+
+ ` ${bounds.width.toFixed(1)}% × ${bounds.height.toFixed(1)}% of the canvas`);
|
|
153
|
+
const canvasOf = (document) => {
|
|
154
|
+
if (!isRecord(document) || !isRecord(document.canvas))
|
|
155
|
+
return undefined;
|
|
156
|
+
const { width, height } = document.canvas;
|
|
157
|
+
return typeof width === 'number' && typeof height === 'number' && width > 0 && height > 0
|
|
158
|
+
? { width, height }
|
|
159
|
+
: undefined;
|
|
160
|
+
};
|
|
161
|
+
const readJson = async (file) => {
|
|
162
|
+
try {
|
|
163
|
+
return JSON.parse(await readFile(file, 'utf8'));
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const fileExists = async (file) => Boolean(await stat(file).then(() => true).catch(() => false));
|
|
170
|
+
/**
|
|
171
|
+
* Resolve one manifest artifact to a file that is actually in this kit.
|
|
172
|
+
*
|
|
173
|
+
* `localPath` is absolute and recorded where the conversion ran, so a moved or
|
|
174
|
+
* copied kit resolves through the basename first. A directory scan closes the
|
|
175
|
+
* remaining gap: freshdesk's kit holds two files for `clean-0` from two
|
|
176
|
+
* attempts, and only the manifest says which one the LayerDoc means.
|
|
177
|
+
*/
|
|
178
|
+
const resolveAssetFile = async (args) => {
|
|
179
|
+
const declared = typeof args.localPath === 'string' && args.localPath ? args.localPath : undefined;
|
|
180
|
+
const basename = declared ? path.basename(declared) : undefined;
|
|
181
|
+
if (basename) {
|
|
182
|
+
const local = path.join(args.assetsDir, basename);
|
|
183
|
+
if (await fileExists(local))
|
|
184
|
+
return { absolute: local, present: true };
|
|
185
|
+
}
|
|
186
|
+
const scanned = args.names.find((name) => name.startsWith(`${args.id}-`) || name === args.id);
|
|
187
|
+
if (scanned)
|
|
188
|
+
return { absolute: path.join(args.assetsDir, scanned), present: true };
|
|
189
|
+
if (declared && await fileExists(declared))
|
|
190
|
+
return { absolute: declared, present: true };
|
|
191
|
+
return { absolute: path.join(args.assetsDir, basename ?? args.id), present: false };
|
|
192
|
+
};
|
|
193
|
+
/** The number a `clean-N`, `cutout-N`, or `crop-N` id carries. */
|
|
194
|
+
const artifactNumber = (id) => {
|
|
195
|
+
const match = /-(\d+)$/u.exec(id);
|
|
196
|
+
return match ? Number(match[1]) : undefined;
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
* Exactly one clean plate is the page's backdrop; the rest are alternates.
|
|
200
|
+
*
|
|
201
|
+
* The document settles which: the plate a background layer references, or —
|
|
202
|
+
* when no layer references one at all — the plate whose number pairs with the
|
|
203
|
+
* largest decoration, because that is the layer it erased. Everything else is
|
|
204
|
+
* the same backdrop minus a further layer, so it is only the background if that
|
|
205
|
+
* layer is left out. Marking them all `ship` is what let a lane ship `clean-1`.
|
|
206
|
+
*/
|
|
207
|
+
const classifyCleanPlates = (args) => {
|
|
208
|
+
const plates = args.assets.filter((asset) => asset.role === 'clean-plate');
|
|
209
|
+
if (plates.length < 2)
|
|
210
|
+
return;
|
|
211
|
+
const layerByNumber = new Map();
|
|
212
|
+
for (const layer of args.rasterLayers) {
|
|
213
|
+
for (const asset of [layer.asset, ...layer.alternates]) {
|
|
214
|
+
const number = asset ? artifactNumber(asset.id) : undefined;
|
|
215
|
+
if (number !== undefined && !layerByNumber.has(number))
|
|
216
|
+
layerByNumber.set(number, layer);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const pairedWith = (plate) => {
|
|
220
|
+
const number = artifactNumber(plate.id);
|
|
221
|
+
return number === undefined ? undefined : layerByNumber.get(number);
|
|
222
|
+
};
|
|
223
|
+
const carried = new Set(args.rasterLayers.flatMap((layer) => (layer.asset ? [layer.asset.id] : [])));
|
|
224
|
+
const base = plates.find((plate) => plate.layer?.kind === 'background' && carried.has(plate.id))
|
|
225
|
+
?? [...plates].sort((left, right) => ((pairedWith(right)?.coverage ?? -1) - (pairedWith(left)?.coverage ?? -1)
|
|
226
|
+
|| left.id.localeCompare(right.id)))[0];
|
|
227
|
+
for (const plate of plates) {
|
|
228
|
+
if (plate.id === base?.id) {
|
|
229
|
+
plate.ship = 'ship';
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
const paired = pairedWith(plate);
|
|
233
|
+
plate.ship = IMPROVE_ALTERNATE_BACKDROP;
|
|
234
|
+
plate.instruction = 'the same backdrop with '
|
|
235
|
+
+ (paired ? `the ${paired.kind} \`${paired.name}\`` : 'a further layer')
|
|
236
|
+
+ ' removed as well. It is the background only if you omit that layer;'
|
|
237
|
+
+ ' otherwise ship the base clean plate.';
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
/** A plate the README calls an alternate must never be listed as one to carry. */
|
|
241
|
+
export const isImproveAlternateBackdrop = (asset) => (asset?.ship === IMPROVE_ALTERNATE_BACKDROP);
|
|
242
|
+
/** The raster layers a plan tells a reader to copy in: alternates are not among them. */
|
|
243
|
+
export const improveCarriedRasterLayers = (layers) => layers.filter((layer) => !isImproveAlternateBackdrop(layer.asset));
|
|
244
|
+
/**
|
|
245
|
+
* Read the kit's LayerDoc and asset manifest into one table the README, the
|
|
246
|
+
* plan, and the stall report all render from.
|
|
247
|
+
*/
|
|
248
|
+
export const readImproveKitAssets = async (args) => {
|
|
249
|
+
const document = args.document ?? await readJson(args.layerDocPath);
|
|
250
|
+
const layerDocPresent = document !== undefined;
|
|
251
|
+
const canvas = canvasOf(document);
|
|
252
|
+
const assetsDir = `${args.layerDocPath}.assets`;
|
|
253
|
+
const manifest = await readJson(path.join(assetsDir, 'manifest.json'));
|
|
254
|
+
const declared = isRecord(manifest) && Array.isArray(manifest.artifacts)
|
|
255
|
+
? manifest.artifacts
|
|
256
|
+
: [];
|
|
257
|
+
const names = await readdir(assetsDir).catch(() => []);
|
|
258
|
+
const leaves = flattenLayerDoc(document);
|
|
259
|
+
const ownerById = new Map();
|
|
260
|
+
leaves.forEach((leaf, index) => {
|
|
261
|
+
for (const { key, id } of artifactIdsOf(leaf)) {
|
|
262
|
+
if (!ownerById.has(id))
|
|
263
|
+
ownerById.set(id, { leaf, index, key });
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
const assets = [];
|
|
267
|
+
for (const artifact of declared) {
|
|
268
|
+
const id = typeof artifact.id === 'string' ? artifact.id : undefined;
|
|
269
|
+
if (!id)
|
|
270
|
+
continue;
|
|
271
|
+
const resolved = await resolveAssetFile({ id, localPath: artifact.localPath, assetsDir, names });
|
|
272
|
+
const owner = ownerById.get(id);
|
|
273
|
+
const box = owner ? boxOfLeaf(owner.leaf) : undefined;
|
|
274
|
+
const bounds = box && canvas ? boundsPct(box, canvas) : undefined;
|
|
275
|
+
const coverage = bounds ? (bounds.width / 100) * (bounds.height / 100) : undefined;
|
|
276
|
+
const role = assetRole(id, artifact.role);
|
|
277
|
+
assets.push({
|
|
278
|
+
id,
|
|
279
|
+
file: path.relative(args.runDir, resolved.absolute),
|
|
280
|
+
role,
|
|
281
|
+
roleLabel: IMPROVE_ASSET_ROLE_COPY[role].label,
|
|
282
|
+
instruction: IMPROVE_ASSET_ROLE_COPY[role].instruction,
|
|
283
|
+
...(owner ? { layer: { kind: owner.leaf.kind ?? 'layer', name: layerName(owner.leaf), index: owner.index } } : {}),
|
|
284
|
+
...(bounds ? { bounds } : {}),
|
|
285
|
+
...(coverage === undefined ? {} : { coverage }),
|
|
286
|
+
hero: coverage !== undefined && coverage >= IMPROVE_HERO_COVERAGE,
|
|
287
|
+
present: resolved.present,
|
|
288
|
+
ship: dispositionByRole(role),
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
assets.sort((left, right) => ((right.coverage ?? -1) - (left.coverage ?? -1) || left.id.localeCompare(right.id)));
|
|
292
|
+
const byId = new Map(assets.map((asset) => [asset.id, asset]));
|
|
293
|
+
const rasterLayers = [];
|
|
294
|
+
leaves.forEach((leaf, index) => {
|
|
295
|
+
const ids = artifactIdsOf(leaf);
|
|
296
|
+
if (ids.length === 0)
|
|
297
|
+
return;
|
|
298
|
+
const box = boxOfLeaf(leaf);
|
|
299
|
+
if (!box || !canvas)
|
|
300
|
+
return;
|
|
301
|
+
const bounds = boundsPct(box, canvas);
|
|
302
|
+
const coverage = (bounds.width / 100) * (bounds.height / 100);
|
|
303
|
+
const carried = ids.map(({ id }) => byId.get(id)).filter((asset) => Boolean(asset));
|
|
304
|
+
rasterLayers.push({
|
|
305
|
+
index,
|
|
306
|
+
kind: leaf.kind ?? 'layer',
|
|
307
|
+
name: layerName(leaf),
|
|
308
|
+
bounds,
|
|
309
|
+
coverage,
|
|
310
|
+
hero: coverage >= IMPROVE_HERO_COVERAGE,
|
|
311
|
+
...(carried[0] ? { asset: carried[0] } : {}),
|
|
312
|
+
alternates: carried.slice(1),
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
rasterLayers.sort((left, right) => right.coverage - left.coverage || left.index - right.index);
|
|
316
|
+
// The LayerDoc settles it: the carrier a layer names is the file to ship, and
|
|
317
|
+
// every other artifact of that layer is an alternate resolution of it.
|
|
318
|
+
for (const layer of rasterLayers) {
|
|
319
|
+
if (layer.asset)
|
|
320
|
+
layer.asset.ship = 'ship';
|
|
321
|
+
for (const alternate of layer.alternates)
|
|
322
|
+
alternate.ship = 'alternate resolution';
|
|
323
|
+
}
|
|
324
|
+
classifyCleanPlates({ assets, rasterLayers });
|
|
325
|
+
return {
|
|
326
|
+
...(canvas ? { canvas } : {}),
|
|
327
|
+
assets,
|
|
328
|
+
rasterLayers,
|
|
329
|
+
layerDocPresent,
|
|
330
|
+
manifestPresent: declared.length > 0,
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
//# sourceMappingURL=improve-kit-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"improve-kit-assets.js","sourceRoot":"","sources":["../src/improve-kit-assets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const IMPROVE_GITIGNORE_PATTERN = ".improve/";
|
|
2
|
+
export declare const IMPROVE_GITIGNORE_COMMENT = "# 12ui improve kits: candidates, captures and targets are not source";
|
|
3
|
+
export type ImproveKitIgnoreState =
|
|
4
|
+
/** This run appended the rule to the repository root `.gitignore`. */
|
|
5
|
+
'ignored'
|
|
6
|
+
/** Some pattern already ignored the out-dir; nothing was written. */
|
|
7
|
+
| 'already-ignored'
|
|
8
|
+
/** Inside a repository, not ignored, and not a kit directory this may claim. */
|
|
9
|
+
| 'not-ignored';
|
|
10
|
+
export type ImproveKitIgnore = {
|
|
11
|
+
state: ImproveKitIgnoreState;
|
|
12
|
+
/** The out-dir relative to the repository root, in POSIX form. */
|
|
13
|
+
relativeOutDir: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Decide, and where it is safe, act. Returns `undefined` when the out-dir is not
|
|
17
|
+
* inside a git working tree — the common case, and the one where the CLI has
|
|
18
|
+
* nothing to say.
|
|
19
|
+
*
|
|
20
|
+
* Only the repository ROOT `.gitignore` is ever written, only by appending, and
|
|
21
|
+
* only when the out-dir is named `.improve` or lives under one. Anything else
|
|
22
|
+
* gets the advisory line instead: guessing a pattern for an arbitrary directory
|
|
23
|
+
* could ignore a lane's source.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ensureImproveKitIgnored: (args: {
|
|
26
|
+
outDir: string;
|
|
27
|
+
}) => Promise<ImproveKitIgnore | undefined>;
|
|
28
|
+
/** The one line a run prints when the kit is committable and nobody said so. */
|
|
29
|
+
export declare const improveKitIgnoreNote: (kit: ImproveKitIgnore | undefined) => string | undefined;
|
|
30
|
+
/** The same fact, in the kit's own status block. */
|
|
31
|
+
export declare const improveKitIgnoreStatusLine: (kit: ImproveKitIgnore | undefined) => string | undefined;
|
|
32
|
+
//# sourceMappingURL=improve-kit-ignore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"improve-kit-ignore.d.ts","sourceRoot":"","sources":["../src/improve-kit-ignore.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,yBAAyB,cAAc,CAAC;AACrD,eAAO,MAAM,yBAAyB,yEACkC,CAAC;AAEzE,MAAM,MAAM,qBAAqB;AAC/B,sEAAsE;AACpE,SAAS;AACX,qEAAqE;GACnE,iBAAiB;AACnB,gFAAgF;GAC9E,aAAa,CAAC;AAElB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAmDF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GAAU,MAAM;IAClD,MAAM,EAAE,MAAM,CAAC;CAChB,KAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAmBvC,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,GAAI,KAAK,gBAAgB,GAAG,SAAS,KAAG,MAAM,GAAG,SAKjF,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,0BAA0B,GAAI,KAAK,gBAAgB,GAAG,SAAS,KAAG,MAAM,GAAG,SAMvF,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { readFile, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
/**
|
|
6
|
+
* Keep the kit out of the repository's history (F17).
|
|
7
|
+
*
|
|
8
|
+
* `--out-dir .improve/<surface>` puts winner PNGs, every candidate, the capture
|
|
9
|
+
* sources and the whole target asset tree inside the repo being improved — about
|
|
10
|
+
* 100 MB of paid artifacts. Nothing said not to commit them, so one wave-2 lane's
|
|
11
|
+
* `git add -A` swept 102 kit files (100.8 MiB) into a seed commit, and the other
|
|
12
|
+
* three lanes each invented the same `.gitignore` rule for themselves. A rule
|
|
13
|
+
* four readers have to invent is a rule the tool owes them.
|
|
14
|
+
*
|
|
15
|
+
* The kit stays advisory: it appends one line when the out-dir is unambiguously a
|
|
16
|
+
* kit directory, says so plainly when it is not, and never fails the run.
|
|
17
|
+
*/
|
|
18
|
+
const execFileAsync = promisify(execFile);
|
|
19
|
+
/** The directory name that makes an out-dir unambiguously a kit, not source. */
|
|
20
|
+
const IMPROVE_KIT_DIRECTORY = '.improve';
|
|
21
|
+
export const IMPROVE_GITIGNORE_PATTERN = '.improve/';
|
|
22
|
+
export const IMPROVE_GITIGNORE_COMMENT = '# 12ui improve kits: candidates, captures and targets are not source';
|
|
23
|
+
const exists = async (file) => (stat(file).then(() => true).catch(() => false));
|
|
24
|
+
/**
|
|
25
|
+
* The repository the out-dir actually sits in, which is not necessarily
|
|
26
|
+
* `--repo`: a lane can point `--repo` at a package and write the kit above it.
|
|
27
|
+
* A `.git` file (worktree, submodule) counts exactly like a `.git` directory.
|
|
28
|
+
*/
|
|
29
|
+
const repositoryRoot = async (from) => {
|
|
30
|
+
let directory = path.resolve(from);
|
|
31
|
+
for (;;) {
|
|
32
|
+
if (await exists(path.join(directory, '.git')))
|
|
33
|
+
return directory;
|
|
34
|
+
const parent = path.dirname(directory);
|
|
35
|
+
if (parent === directory)
|
|
36
|
+
return undefined;
|
|
37
|
+
directory = parent;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const LITERAL_PATTERNS = new Set(['.improve', '.improve/', '/.improve', '/.improve/']);
|
|
41
|
+
/** The fallback when git cannot be run at all: does the root file say it already? */
|
|
42
|
+
const literallyIgnored = async (gitignore) => {
|
|
43
|
+
const text = await readFile(gitignore, 'utf8').catch(() => '');
|
|
44
|
+
return text.split('\n').some((line) => LITERAL_PATTERNS.has(line.trim()));
|
|
45
|
+
};
|
|
46
|
+
/** `true`/`false` from git itself; `undefined` when git could not answer. */
|
|
47
|
+
const gitIgnores = async (root, relative) => {
|
|
48
|
+
try {
|
|
49
|
+
await execFileAsync('git', ['check-ignore', '-q', '--', relative], { cwd: root });
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return error.code === 1 ? false : undefined;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const appendRule = async (gitignore) => {
|
|
57
|
+
const existing = await readFile(gitignore, 'utf8').catch(() => undefined);
|
|
58
|
+
const separator = existing === undefined || existing.length === 0
|
|
59
|
+
? ''
|
|
60
|
+
: existing.endsWith('\n') ? '\n' : '\n\n';
|
|
61
|
+
await writeFile(gitignore, `${existing ?? ''}${separator}${IMPROVE_GITIGNORE_COMMENT}\n${IMPROVE_GITIGNORE_PATTERN}\n`, 'utf8');
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Decide, and where it is safe, act. Returns `undefined` when the out-dir is not
|
|
65
|
+
* inside a git working tree — the common case, and the one where the CLI has
|
|
66
|
+
* nothing to say.
|
|
67
|
+
*
|
|
68
|
+
* Only the repository ROOT `.gitignore` is ever written, only by appending, and
|
|
69
|
+
* only when the out-dir is named `.improve` or lives under one. Anything else
|
|
70
|
+
* gets the advisory line instead: guessing a pattern for an arbitrary directory
|
|
71
|
+
* could ignore a lane's source.
|
|
72
|
+
*/
|
|
73
|
+
export const ensureImproveKitIgnored = async (args) => {
|
|
74
|
+
try {
|
|
75
|
+
const outDir = path.resolve(args.outDir);
|
|
76
|
+
const root = await repositoryRoot(outDir);
|
|
77
|
+
if (!root || root === outDir)
|
|
78
|
+
return undefined;
|
|
79
|
+
const relative = path.relative(root, outDir).split(path.sep).join('/');
|
|
80
|
+
if (!relative || relative.startsWith('../'))
|
|
81
|
+
return undefined;
|
|
82
|
+
const gitignore = path.join(root, '.gitignore');
|
|
83
|
+
const ignored = await gitIgnores(root, relative) ?? await literallyIgnored(gitignore);
|
|
84
|
+
if (ignored)
|
|
85
|
+
return { state: 'already-ignored', relativeOutDir: relative };
|
|
86
|
+
if (!relative.split('/').includes(IMPROVE_KIT_DIRECTORY)) {
|
|
87
|
+
return { state: 'not-ignored', relativeOutDir: relative };
|
|
88
|
+
}
|
|
89
|
+
await appendRule(gitignore);
|
|
90
|
+
return { state: 'ignored', relativeOutDir: relative };
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Advisory work never sinks a run that has already spent money.
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
/** The one line a run prints when the kit is committable and nobody said so. */
|
|
98
|
+
export const improveKitIgnoreNote = (kit) => (kit?.state === 'not-ignored'
|
|
99
|
+
? 'The kit is inside the repository and is not git-ignored;'
|
|
100
|
+
+ ` add ${kit.relativeOutDir}/ to .gitignore before committing.`
|
|
101
|
+
: undefined);
|
|
102
|
+
/** The same fact, in the kit's own status block. */
|
|
103
|
+
export const improveKitIgnoreStatusLine = (kit) => {
|
|
104
|
+
if (!kit)
|
|
105
|
+
return undefined;
|
|
106
|
+
return kit.state === 'not-ignored'
|
|
107
|
+
? `Kit: not git-ignored — see the note; add \`${kit.relativeOutDir}/\` to .gitignore`
|
|
108
|
+
+ ' before committing.'
|
|
109
|
+
: 'Kit: git-ignored via .gitignore.';
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=improve-kit-ignore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"improve-kit-ignore.js","sourceRoot":"","sources":["../src/improve-kit-ignore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
1
|
+
import { type ImproveKitAssetIndex } from './improve-kit-assets.js';
|
|
2
|
+
import { type ImproveKitStatus } from './improve-kit-status.js';
|
|
3
|
+
import { type ImproveRecord, type ImproveStage } from './improve-workspace.js';
|
|
4
|
+
export declare const renderImproveReadme: (args: {
|
|
5
|
+
record: ImproveRecord;
|
|
6
|
+
status: ImproveKitStatus;
|
|
7
|
+
index: ImproveKitAssetIndex;
|
|
8
|
+
}) => string;
|
|
9
|
+
export declare const writeImproveReadme: (record: ImproveRecord, context?: {
|
|
10
|
+
requestedTo?: ImproveStage;
|
|
11
|
+
}) => Promise<string>;
|
|
3
12
|
//# sourceMappingURL=improve-kit-readme.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"improve-kit-readme.d.ts","sourceRoot":"","sources":["../src/improve-kit-readme.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"improve-kit-readme.d.ts","sourceRoot":"","sources":["../src/improve-kit-readme.ts"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAOL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAwT7F,eAAO,MAAM,mBAAmB,GAAI,MAAM;IACxC,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,oBAAoB,CAAC;CAC7B,KAAG,MAmBQ,CAAC;AAEb,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,aAAa,EACrB,UAAS;IAAE,WAAW,CAAC,EAAE,YAAY,CAAA;CAAO,KAC3C,OAAO,CAAC,MAAM,CAQhB,CAAC"}
|