@whittlelabs/sifter 0.24.1 → 0.26.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.
- package/bin.js +63 -1
- package/bin.js.map +2 -2
- package/package.json +1 -1
package/bin.js
CHANGED
|
@@ -19502,10 +19502,45 @@ var require_output_gates = __commonJS({
|
|
|
19502
19502
|
"../../packages/shuttle/dist/executors/output-gates.js"(exports2) {
|
|
19503
19503
|
"use strict";
|
|
19504
19504
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
19505
|
+
exports2.isSanctionedPaint = isSanctionedPaint;
|
|
19506
|
+
exports2.unsanctionedPaints = unsanctionedPaints;
|
|
19505
19507
|
exports2.resolvePath = resolvePath;
|
|
19506
19508
|
exports2.evaluateOutputGates = evaluateOutputGates;
|
|
19507
19509
|
exports2.renderRepairPrompt = renderRepairPrompt;
|
|
19508
19510
|
var INPUT_REF = "input:";
|
|
19511
|
+
var COLOR_BEARING = ["fill", "stroke", "color", "stop-color", "flood-color", "lighting-color"];
|
|
19512
|
+
var INERT = /* @__PURE__ */ new Set(["none", "inherit", "initial", "unset", "transparent", "currentcolor"]);
|
|
19513
|
+
function isSanctionedPaint(raw) {
|
|
19514
|
+
const value = raw.trim().toLowerCase();
|
|
19515
|
+
if (value === "")
|
|
19516
|
+
return true;
|
|
19517
|
+
if (INERT.has(value))
|
|
19518
|
+
return true;
|
|
19519
|
+
if (/^url\(\s*['"]?#[^)'"]+['"]?\s*\)$/.test(value))
|
|
19520
|
+
return true;
|
|
19521
|
+
const varMatch = /^var\(\s*(--[a-z0-9-]+)\s*(?:,([\s\S]*))?\)$/.exec(value);
|
|
19522
|
+
if (!varMatch)
|
|
19523
|
+
return false;
|
|
19524
|
+
const [, name, fallback] = varMatch;
|
|
19525
|
+
if (!name.startsWith("--color-"))
|
|
19526
|
+
return false;
|
|
19527
|
+
return fallback === void 0 || isSanctionedPaint(fallback);
|
|
19528
|
+
}
|
|
19529
|
+
function unsanctionedPaints(source) {
|
|
19530
|
+
const found = [];
|
|
19531
|
+
const attrs = COLOR_BEARING.join("|");
|
|
19532
|
+
const attribute = new RegExp(`\\b(?:${attrs})\\s*=\\s*(['"])([\\s\\S]*?)\\1`, "gi");
|
|
19533
|
+
const declaration = new RegExp(`\\b(?:${attrs})\\s*:\\s*([^;"'}\\n]+)`, "gi");
|
|
19534
|
+
for (const [, , value] of source.matchAll(attribute)) {
|
|
19535
|
+
if (!isSanctionedPaint(value))
|
|
19536
|
+
found.push(value.trim());
|
|
19537
|
+
}
|
|
19538
|
+
for (const [, value] of source.matchAll(declaration)) {
|
|
19539
|
+
if (!isSanctionedPaint(value))
|
|
19540
|
+
found.push(value.trim());
|
|
19541
|
+
}
|
|
19542
|
+
return found;
|
|
19543
|
+
}
|
|
19509
19544
|
function resolvePath(root, path) {
|
|
19510
19545
|
let ctx = root;
|
|
19511
19546
|
for (const seg of path.split(".")) {
|
|
@@ -19593,6 +19628,33 @@ var require_output_gates = __commonJS({
|
|
|
19593
19628
|
return [
|
|
19594
19629
|
`'${path}' must be a non-empty array${cond}; it was ${Array.isArray(value) ? "empty" : "absent"}.`
|
|
19595
19630
|
];
|
|
19631
|
+
},
|
|
19632
|
+
/**
|
|
19633
|
+
* `bounded_palette` — every colour in the sources at `path` must be named
|
|
19634
|
+
* by role rather than written as a value. Params:
|
|
19635
|
+
* `{ path: <output path>, roles?: <role names for the repair turn> }`.
|
|
19636
|
+
*
|
|
19637
|
+
* A drawing the model authors is markup the house did not write, and a
|
|
19638
|
+
* literal in it is a colour outside the consuming palette: unproved
|
|
19639
|
+
* against the colours beside it, unchecked for contrast on the ground it
|
|
19640
|
+
* lands on, and fixed to one theme. The consumer strips such a paint at
|
|
19641
|
+
* render, so an artifact that carries one silently loses it. Catching it
|
|
19642
|
+
* HERE is what makes that a repair the model can make while it still has
|
|
19643
|
+
* the drawing in hand, instead of a defect nobody sees until the picture
|
|
19644
|
+
* comes out plain.
|
|
19645
|
+
*/
|
|
19646
|
+
bounded_palette(params, output) {
|
|
19647
|
+
const path = String(params.path);
|
|
19648
|
+
const value = resolvePath(output, path);
|
|
19649
|
+
const sources = (Array.isArray(value) ? value : [value]).filter((v) => typeof v === "string" && v.length > 0);
|
|
19650
|
+
const offenders = [...new Set(sources.flatMap(unsanctionedPaints))];
|
|
19651
|
+
if (offenders.length === 0)
|
|
19652
|
+
return [];
|
|
19653
|
+
const roles = Array.isArray(params.roles) ? params.roles.map(String) : [];
|
|
19654
|
+
const vocabulary = roles.length > 0 ? ` Use one of: ${roles.join(", ")}.` : "";
|
|
19655
|
+
return [
|
|
19656
|
+
`'${path}' states ${offenders.length} colour value${offenders.length === 1 ? "" : "s"} directly (${offenders.slice(0, 8).join(", ")}${offenders.length > 8 ? ", \u2026" : ""}). Every colour must be named by role \u2014 var(--color-\u2026), currentColor, or none \u2014 never as a hex, rgb(), hsl() or colour name, because a value cannot adapt to the reader's theme and was never checked against the colours beside it.${vocabulary} Redraw with roles and return the whole output again.`
|
|
19657
|
+
];
|
|
19596
19658
|
}
|
|
19597
19659
|
};
|
|
19598
19660
|
function evaluateOutputGates(gates, output, inputs) {
|
|
@@ -22371,7 +22433,7 @@ var import_path = require("path");
|
|
|
22371
22433
|
var import_promises = require("fs/promises");
|
|
22372
22434
|
var import_yaml = __toESM(require_dist());
|
|
22373
22435
|
var import_shuttle = __toESM(require_dist5());
|
|
22374
|
-
var buildVersion = true ? "0.
|
|
22436
|
+
var buildVersion = true ? "0.26.0" : pkg.version;
|
|
22375
22437
|
var sifterBrand = {
|
|
22376
22438
|
product: {
|
|
22377
22439
|
id: "sifter",
|