@basiclines/rampa 1.1.3 → 1.3.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 (3) hide show
  1. package/README.md +61 -0
  2. package/dist/index.js +343 -11
  3. package/package.json +7 -3
package/README.md CHANGED
@@ -140,6 +140,35 @@ Available types:
140
140
  | `--output` | `-O` | Output format: text, json, css | text |
141
141
  | `--preview` | | Show colored squares | true |
142
142
 
143
+ ### Accessibility
144
+
145
+ | Flag | Alias | Description | Default |
146
+ |------|-------|-------------|---------|
147
+ | `--accessibility` | `-A` | APCA contrast report | off |
148
+
149
+ The `-A` flag generates an accessibility report using the [APCA](https://github.com/Myndex/APCA) (Accessible Perceptual Contrast Algorithm) methodology. It analyzes all color pairs across all generated ramps and groups passing pairs by contrast level.
150
+
151
+ **Filter options:**
152
+
153
+ | Syntax | Example | Description |
154
+ |--------|---------|-------------|
155
+ | `-A` | `-A` | Show all passing pairs |
156
+ | `-A=<Lc>` | `-A=60` | Minimum Lc threshold |
157
+ | `-A=<label>` | `-A=body` | Filter by named level |
158
+ | `-A=<min>:<max>` | `-A=15:30` | Lc range filter |
159
+ | `-A=<label>:<label>` | `-A=nontext:bold` | Range using level names |
160
+
161
+ **Level labels:**
162
+
163
+ | Label | Lc Threshold | Use Case |
164
+ |-------|-------------|----------|
165
+ | `preferred` | 90 | Preferred body text |
166
+ | `body` | 75 | Body text |
167
+ | `large` | 60 | Large text |
168
+ | `bold` | 45 | Large/bold text |
169
+ | `minimum` | 30 | Minimum text |
170
+ | `nontext` | 15 | Non-text elements |
171
+
143
172
  ### Other
144
173
 
145
174
  | Flag | Alias | Description |
@@ -251,6 +280,28 @@ Output:
251
280
  rampa -C "#3b82f6" --no-preview | head -5
252
281
  ```
253
282
 
283
+ ### Accessibility Report
284
+
285
+ ```bash
286
+ # Full APCA contrast report
287
+ rampa -C "#3b82f6" --add=complementary -A
288
+
289
+ # Filter by minimum Lc threshold
290
+ rampa -C "#3b82f6" --add=complementary -A=body
291
+
292
+ # Filter by Lc range
293
+ rampa -C "#3b82f6" --add=complementary -A=15:30
294
+
295
+ # Filter using level labels
296
+ rampa -C "#3b82f6" --add=complementary -A=nontext:bold
297
+
298
+ # Accessibility report in JSON
299
+ rampa -C "#3b82f6" --add=complementary -A -O json
300
+
301
+ # Accessibility report in CSS (appended as comment)
302
+ rampa -C "#3b82f6" --add=complementary -A -O css
303
+ ```
304
+
254
305
  ## Contextual Help
255
306
 
256
307
  Run any flag without a value to see detailed help:
@@ -280,6 +331,16 @@ bun run build
280
331
  bun run build:all
281
332
  ```
282
333
 
334
+ ## AI Evals
335
+
336
+ Compare how different LLM models use the Rampa CLI by sending the same prompt to multiple models in agent mode. Models can discover rampa via `--help`, execute commands, and iterate. Use `--raw` to run without rampa for baseline comparison. See [evals/README.md](evals/README.md) for details.
337
+
338
+ ```bash
339
+ bun run eval # all prompts, all models
340
+ bun run eval --prompt ghostty-matrix-theme --no-judge # single prompt
341
+ bun run eval --prompt ghostty-matrix-theme --raw # without rampa (baseline)
342
+ ```
343
+
283
344
  ## Build Targets
284
345
 
285
346
  ```bash
package/dist/index.js CHANGED
@@ -9518,8 +9518,8 @@ var calculateHue = (config, position, baseHue, middleIndex, i2) => {
9518
9518
  };
9519
9519
  var calculateSaturation = (config, position, baseSaturation, middleIndex, i2) => {
9520
9520
  try {
9521
- const startSaturation = config.saturationStart / 100;
9522
- const endSaturation = config.saturationEnd / 100;
9521
+ const startSaturation = config.saturationStart / 100 * baseSaturation;
9522
+ const endSaturation = config.saturationEnd / 100 * baseSaturation;
9523
9523
  const newSaturation = startSaturation + (endSaturation - startSaturation) * position;
9524
9524
  return clampValue2(newSaturation, 0, 1);
9525
9525
  } catch (error) {
@@ -9943,6 +9943,291 @@ ${dim}For accurate color previews, use a terminal with COLORTERM=truecolor.${res
9943
9943
  return null;
9944
9944
  }
9945
9945
 
9946
+ // node_modules/apca-w3/src/apca-w3.js
9947
+ var SA98G = {
9948
+ mainTRC: 2.4,
9949
+ get mainTRCencode() {
9950
+ return 1 / this.mainTRC;
9951
+ },
9952
+ sRco: 0.2126729,
9953
+ sGco: 0.7151522,
9954
+ sBco: 0.072175,
9955
+ normBG: 0.56,
9956
+ normTXT: 0.57,
9957
+ revTXT: 0.62,
9958
+ revBG: 0.65,
9959
+ blkThrs: 0.022,
9960
+ blkClmp: 1.414,
9961
+ scaleBoW: 1.14,
9962
+ scaleWoB: 1.14,
9963
+ loBoWoffset: 0.027,
9964
+ loWoBoffset: 0.027,
9965
+ deltaYmin: 0.0005,
9966
+ loClip: 0.1,
9967
+ mFactor: 1.9468554433171,
9968
+ get mFactInv() {
9969
+ return 1 / this.mFactor;
9970
+ },
9971
+ mOffsetIn: 0.0387393816571401,
9972
+ mExpAdj: 0.283343396420869,
9973
+ get mExp() {
9974
+ return this.mExpAdj / this.blkClmp;
9975
+ },
9976
+ mOffsetOut: 0.312865795870758
9977
+ };
9978
+ function APCAcontrast(txtY, bgY, places = -1) {
9979
+ const icp = [0, 1.1];
9980
+ if (isNaN(txtY) || isNaN(bgY) || Math.min(txtY, bgY) < icp[0] || Math.max(txtY, bgY) > icp[1]) {
9981
+ return 0;
9982
+ }
9983
+ let SAPC = 0;
9984
+ let outputContrast = 0;
9985
+ let polCat = "BoW";
9986
+ txtY = txtY > SA98G.blkThrs ? txtY : txtY + Math.pow(SA98G.blkThrs - txtY, SA98G.blkClmp);
9987
+ bgY = bgY > SA98G.blkThrs ? bgY : bgY + Math.pow(SA98G.blkThrs - bgY, SA98G.blkClmp);
9988
+ if (Math.abs(bgY - txtY) < SA98G.deltaYmin) {
9989
+ return 0;
9990
+ }
9991
+ if (bgY > txtY) {
9992
+ SAPC = (Math.pow(bgY, SA98G.normBG) - Math.pow(txtY, SA98G.normTXT)) * SA98G.scaleBoW;
9993
+ outputContrast = SAPC < SA98G.loClip ? 0 : SAPC - SA98G.loBoWoffset;
9994
+ } else {
9995
+ polCat = "WoB";
9996
+ SAPC = (Math.pow(bgY, SA98G.revBG) - Math.pow(txtY, SA98G.revTXT)) * SA98G.scaleWoB;
9997
+ outputContrast = SAPC > -SA98G.loClip ? 0 : SAPC + SA98G.loWoBoffset;
9998
+ }
9999
+ if (places < 0) {
10000
+ return outputContrast * 100;
10001
+ } else if (places == 0) {
10002
+ return Math.round(Math.abs(outputContrast) * 100) + "<sub>" + polCat + "</sub>";
10003
+ } else if (Number.isInteger(places)) {
10004
+ return (outputContrast * 100).toFixed(places);
10005
+ } else {
10006
+ return 0;
10007
+ }
10008
+ }
10009
+ function sRGBtoY(rgb10 = [0, 0, 0]) {
10010
+ function simpleExp(chan) {
10011
+ return Math.pow(chan / 255, SA98G.mainTRC);
10012
+ }
10013
+ return SA98G.sRco * simpleExp(rgb10[0]) + SA98G.sGco * simpleExp(rgb10[1]) + SA98G.sBco * simpleExp(rgb10[2]);
10014
+ }
10015
+
10016
+ // src/accessibility/apca.ts
10017
+ var APCA_LEVELS = [
10018
+ { id: "preferred-body", name: "Preferred body text", minLc: 90 },
10019
+ { id: "body", name: "Body text", minLc: 75 },
10020
+ { id: "large", name: "Large text", minLc: 60 },
10021
+ { id: "large-bold", name: "Large/bold text", minLc: 45 },
10022
+ { id: "min-text", name: "Minimum text", minLc: 30 },
10023
+ { id: "non-text", name: "Non-text", minLc: 15 }
10024
+ ];
10025
+ var LEVEL_ALIASES = {
10026
+ preferred: 90,
10027
+ body: 75,
10028
+ large: 60,
10029
+ bold: 45,
10030
+ minimum: 30,
10031
+ nontext: 15
10032
+ };
10033
+ function resolveValue2(val) {
10034
+ const num9 = parseFloat(val);
10035
+ if (!isNaN(num9) && num9 >= 0)
10036
+ return num9;
10037
+ const label = val.toLowerCase().trim();
10038
+ if (label in LEVEL_ALIASES)
10039
+ return LEVEL_ALIASES[label];
10040
+ return null;
10041
+ }
10042
+ function parseAccessibilityFilter(value) {
10043
+ const raw = value ?? "";
10044
+ if (!value || value === "" || value === "true")
10045
+ return { min: 0, max: Infinity, raw };
10046
+ if (value.includes(":")) {
10047
+ const [startStr, endStr] = value.split(":");
10048
+ const start = resolveValue2(startStr);
10049
+ const end = resolveValue2(endStr);
10050
+ if (start === null || end === null) {
10051
+ const validLabels2 = Object.keys(LEVEL_ALIASES).join(", ");
10052
+ console.error(`Error: Invalid accessibility range "${value}". Use Lc numbers or labels: ${validLabels2}`);
10053
+ process.exit(1);
10054
+ }
10055
+ const lo = Math.min(start, end);
10056
+ const hi = Math.max(start, end);
10057
+ return { min: lo, max: hi, raw: value };
10058
+ }
10059
+ const resolved = resolveValue2(value);
10060
+ if (resolved !== null)
10061
+ return { min: resolved, max: Infinity, raw: value };
10062
+ const validLabels = Object.keys(LEVEL_ALIASES).join(", ");
10063
+ console.error(`Error: Invalid accessibility filter "${value}". Use a Lc number, label, or range (e.g. 15:30). Labels: ${validLabels}`);
10064
+ process.exit(1);
10065
+ }
10066
+ function computeApca(fgHex, bgHex) {
10067
+ const [fgR, fgG, fgB] = chroma_js_default(fgHex).rgb();
10068
+ const [bgR, bgG, bgB] = chroma_js_default(bgHex).rgb();
10069
+ return APCAcontrast(sRGBtoY([fgR, fgG, fgB]), sRGBtoY([bgR, bgG, bgB]));
10070
+ }
10071
+ function getPassingLevels(lc) {
10072
+ const absLc = Math.abs(lc);
10073
+ return APCA_LEVELS.filter((level) => absLc >= level.minLc);
10074
+ }
10075
+
10076
+ // src/accessibility/report.ts
10077
+ function collectColors(ramps) {
10078
+ const refs = [];
10079
+ for (const ramp of ramps) {
10080
+ for (let i2 = 0;i2 < ramp.colors.length; i2++) {
10081
+ refs.push({ ramp: ramp.name, index: i2, color: ramp.colors[i2] });
10082
+ }
10083
+ }
10084
+ return refs;
10085
+ }
10086
+ function deduplicateColors(colors2) {
10087
+ if (colors2.length <= 2)
10088
+ return colors2;
10089
+ const keep = new Set;
10090
+ keep.add(0);
10091
+ keep.add(colors2.length - 1);
10092
+ for (let i2 = 1;i2 < colors2.length; i2++) {
10093
+ const prev = colors2[i2 - 1];
10094
+ const curr = colors2[i2];
10095
+ if (curr.ramp !== prev.ramp) {
10096
+ keep.add(i2);
10097
+ keep.add(i2 - 1);
10098
+ continue;
10099
+ }
10100
+ const de = chroma_js_default.deltaE(curr.color, prev.color);
10101
+ if (de >= 3) {
10102
+ keep.add(i2);
10103
+ }
10104
+ }
10105
+ return colors2.filter((_3, i2) => keep.has(i2));
10106
+ }
10107
+ var DEFAULT_FILTER = { min: 0, max: Infinity, raw: "" };
10108
+ function generateAccessibilityReport(ramps, filter = DEFAULT_FILTER) {
10109
+ const allColors = collectColors(ramps);
10110
+ const colors2 = deduplicateColors(allColors);
10111
+ const totalPairs = colors2.length * (colors2.length - 1) / 2;
10112
+ const levelMap = new Map;
10113
+ for (const level of APCA_LEVELS) {
10114
+ levelMap.set(level.id, []);
10115
+ }
10116
+ let passingPairs = 0;
10117
+ for (let i2 = 0;i2 < colors2.length; i2++) {
10118
+ for (let j = i2 + 1;j < colors2.length; j++) {
10119
+ const a2 = colors2[i2];
10120
+ const b2 = colors2[j];
10121
+ const lcAB = computeApca(a2.color, b2.color);
10122
+ const lcBA = computeApca(b2.color, a2.color);
10123
+ const bestAbsLc = Math.max(Math.abs(lcAB), Math.abs(lcBA));
10124
+ const passing = getPassingLevels(bestAbsLc);
10125
+ if (passing.length > 0) {
10126
+ passingPairs++;
10127
+ const pair = {
10128
+ colorA: a2,
10129
+ colorB: b2,
10130
+ lcAB: Math.round(lcAB * 100) / 100,
10131
+ lcBA: Math.round(lcBA * 100) / 100
10132
+ };
10133
+ const highest = passing[0];
10134
+ levelMap.get(highest.id).push(pair);
10135
+ }
10136
+ }
10137
+ }
10138
+ const levels = APCA_LEVELS.filter((level) => level.minLc >= filter.min && level.minLc <= filter.max).map((level) => {
10139
+ const pairs = filter.max < Infinity ? levelMap.get(level.id).filter((p) => {
10140
+ const bestAbsLc = Math.max(Math.abs(p.lcAB), Math.abs(p.lcBA));
10141
+ return bestAbsLc >= filter.min && bestAbsLc <= filter.max;
10142
+ }) : levelMap.get(level.id);
10143
+ return { id: level.id, name: level.name, minLc: level.minLc, pairs };
10144
+ });
10145
+ return {
10146
+ totalPairs,
10147
+ passingPairs,
10148
+ levels,
10149
+ filter
10150
+ };
10151
+ }
10152
+
10153
+ // src/formatters/accessibility-json.ts
10154
+ function formatAccessibilityJson(report) {
10155
+ return {
10156
+ totalPairs: report.totalPairs,
10157
+ passingPairs: report.passingPairs,
10158
+ filter: report.filter.raw ? { value: report.filter.raw, min: report.filter.min, max: report.filter.max === Infinity ? null : report.filter.max } : null,
10159
+ levels: report.levels.map((level) => ({
10160
+ id: level.id,
10161
+ name: level.name,
10162
+ minLc: level.minLc,
10163
+ count: level.pairs.length,
10164
+ pairs: level.pairs.map((pair) => ({
10165
+ colorA: { ramp: pair.colorA.ramp, index: pair.colorA.index, color: pair.colorA.color },
10166
+ colorB: { ramp: pair.colorB.ramp, index: pair.colorB.index, color: pair.colorB.color },
10167
+ lcAB: pair.lcAB,
10168
+ lcBA: pair.lcBA
10169
+ }))
10170
+ }))
10171
+ };
10172
+ }
10173
+
10174
+ // src/formatters/accessibility-text.ts
10175
+ function formatLc(lc) {
10176
+ const str = lc.toString();
10177
+ return lc >= 0 ? ` ${str}` : str;
10178
+ }
10179
+ function pairSquares(pair) {
10180
+ const [rA, gA, bA] = chroma_js_default(pair.colorA.color).rgb();
10181
+ const [rB, gB, bB] = chroma_js_default(pair.colorB.color).rgb();
10182
+ return `${coloredSquare(rA, gA, bA)}${coloredSquare(rB, gB, bB)}`;
10183
+ }
10184
+ function formatAccessibilityText(report, options = {}) {
10185
+ const lines = [];
10186
+ const showPreview = options.preview ?? false;
10187
+ lines.push("");
10188
+ lines.push("# Accessibility Report (APCA)");
10189
+ lines.push(`${report.passingPairs} of ${report.totalPairs} pairs pass at least one level`);
10190
+ lines.push("");
10191
+ const filteredPairCount = report.levels.reduce((sum, l2) => sum + l2.pairs.length, 0);
10192
+ if (filteredPairCount === 0) {
10193
+ const filterDesc = report.filter.raw ? `filter: ${report.filter.raw}` : "current filter";
10194
+ lines.push(`No pairs match the ${filterDesc}`);
10195
+ lines.push("");
10196
+ return lines.join(`
10197
+ `);
10198
+ }
10199
+ for (const level of report.levels) {
10200
+ if (level.pairs.length === 0)
10201
+ continue;
10202
+ lines.push(`## ${level.name} (Lc ≥ ${level.minLc}) — ${level.pairs.length} pairs`);
10203
+ const maxColorA = Math.max(...level.pairs.map((p) => p.colorA.color.length));
10204
+ const maxColorB = Math.max(...level.pairs.map((p) => p.colorB.color.length));
10205
+ const maxLcAB = Math.max(...level.pairs.map((p) => formatLc(p.lcAB).length));
10206
+ const maxLcBA = Math.max(...level.pairs.map((p) => formatLc(p.lcBA).length));
10207
+ const maxRefA = Math.max(...level.pairs.map((p) => `${p.colorA.ramp}[${p.colorA.index}]`.length));
10208
+ const maxRefB = Math.max(...level.pairs.map((p) => `${p.colorB.ramp}[${p.colorB.index}]`.length));
10209
+ for (const pair of level.pairs) {
10210
+ const colA = pair.colorA.color.padEnd(maxColorA);
10211
+ const colB = pair.colorB.color.padEnd(maxColorB);
10212
+ const lcA = formatLc(pair.lcAB).padStart(maxLcAB);
10213
+ const lcB = formatLc(pair.lcBA).padStart(maxLcBA);
10214
+ const refA = `${pair.colorA.ramp}[${pair.colorA.index}]`.padEnd(maxRefA);
10215
+ const refB = `${pair.colorB.ramp}[${pair.colorB.index}]`.padEnd(maxRefB);
10216
+ const preview = showPreview ? `${pairSquares(pair)} ` : "";
10217
+ lines.push(` ${preview}${colA} ↔ ${colB} Lc ${lcA} / ${lcB} ${refA} ↔ ${refB}`);
10218
+ }
10219
+ lines.push("");
10220
+ }
10221
+ return lines.join(`
10222
+ `);
10223
+ }
10224
+ function formatAccessibilityCss(report) {
10225
+ return `
10226
+ /*
10227
+ ` + formatAccessibilityText(report) + `*/
10228
+ `;
10229
+ }
10230
+
9946
10231
  // src/index.ts
9947
10232
  if (process.argv.includes("--help") || process.argv.includes("-h")) {
9948
10233
  showHelp();
@@ -9952,7 +10237,7 @@ function showHelp() {
9952
10237
  const dim = "\x1B[2m";
9953
10238
  const reset = "\x1B[0m";
9954
10239
  const help = `
9955
- rampa v1.1.3
10240
+ rampa v1.2.0
9956
10241
  Generate mathematically accurate color palettes from a base color
9957
10242
 
9958
10243
  USAGE
@@ -9995,6 +10280,10 @@ HARMONIES
9995
10280
  OUTPUT
9996
10281
  ${cyan}-O, --output <format>${reset} ${dim}Output format (default: text)${reset}
9997
10282
  ${cyan}--preview / --no-preview${reset} ${dim}Show colored squares (default: true)${reset}
10283
+ ${cyan}-A, --accessibility [filter]${reset} ${dim}Show APCA contrast report${reset}
10284
+
10285
+ ${dim}Filters: preferred, body, large, bold, minimum, nontext${reset}
10286
+ ${dim}or a custom Lc value (e.g. 60)${reset}
9998
10287
 
9999
10288
  ${dim}Formats: text, json, css${reset}
10000
10289
 
@@ -10009,6 +10298,8 @@ EXAMPLES
10009
10298
  ${cyan}rampa -C "#3b82f6" --add=shift:45 --add=shift:90${reset}
10010
10299
  ${cyan}rampa -C "#3b82f6" -O css${reset}
10011
10300
  ${cyan}rampa -C "#3b82f6" --tint-color="#FF0000" --tint-opacity=15${reset}
10301
+ ${cyan}rampa -C "#3b82f6" -A${reset}
10302
+ ${cyan}rampa -C "#3b82f6" --add=complementary -O json -A${reset}
10012
10303
  `;
10013
10304
  console.log(help.trim());
10014
10305
  process.exit(0);
@@ -10148,6 +10439,25 @@ Examples:
10148
10439
  rampa -C "#3b82f6" --output=json
10149
10440
  rampa -C "#3b82f6" --output=css
10150
10441
  rampa -C "#3b82f6" -O json --add=complementary
10442
+ `,
10443
+ accessibility: `
10444
+ -A, --accessibility [filter] Show APCA contrast report
10445
+
10446
+ Filters (optional):
10447
+ preferred Lc ≥ 90 Preferred body text
10448
+ body Lc ≥ 75 Body text
10449
+ large Lc ≥ 60 Large text
10450
+ bold Lc ≥ 45 Large/bold text
10451
+ minimum Lc ≥ 30 Minimum text
10452
+ nontext Lc ≥ 15 Non-text
10453
+ <number> Custom Lc threshold (e.g. 60)
10454
+
10455
+ Examples:
10456
+ rampa -C "#3b82f6" -A
10457
+ rampa -C "#3b82f6" -A body
10458
+ rampa -C "#3b82f6" -A=large
10459
+ rampa -C "#3b82f6" --accessibility=75
10460
+ rampa -C "#3b82f6" -O json -A preferred
10151
10461
  `
10152
10462
  };
10153
10463
  function showFlagHelp(flag) {
@@ -10190,13 +10500,13 @@ var validFormats = ["hex", "hsl", "rgb", "oklch"];
10190
10500
  var main = defineCommand({
10191
10501
  meta: {
10192
10502
  name: "rampa",
10193
- version: "1.1.3",
10503
+ version: "1.3.0",
10194
10504
  description: "Generate mathematically accurate color palettes from a base color"
10195
10505
  },
10196
10506
  args: {
10197
10507
  color: {
10198
10508
  type: "string",
10199
- alias: "C",
10509
+ alias: ["C", "c"],
10200
10510
  description: "Base color (hex, hsl, rgb, oklch)",
10201
10511
  required: true
10202
10512
  },
@@ -10207,18 +10517,18 @@ var main = defineCommand({
10207
10517
  },
10208
10518
  format: {
10209
10519
  type: "string",
10210
- alias: "F",
10520
+ alias: ["F", "f"],
10211
10521
  description: "Output format: hex, hsl, rgb, oklch (default: same as input)"
10212
10522
  },
10213
10523
  lightness: {
10214
10524
  type: "string",
10215
- alias: "L",
10525
+ alias: ["L", "l"],
10216
10526
  description: "Lightness range start:end (0-100, default: 0:100)",
10217
10527
  default: "0:100"
10218
10528
  },
10219
10529
  saturation: {
10220
10530
  type: "string",
10221
- alias: "S",
10531
+ alias: ["S", "s"],
10222
10532
  description: "Saturation range start:end (0-100, default: 100:0)",
10223
10533
  default: "100:0"
10224
10534
  },
@@ -10268,9 +10578,14 @@ var main = defineCommand({
10268
10578
  },
10269
10579
  output: {
10270
10580
  type: "string",
10271
- alias: "O",
10581
+ alias: ["O", "o"],
10272
10582
  description: "Output format: text, json, css (default: text)",
10273
10583
  default: "text"
10584
+ },
10585
+ accessibility: {
10586
+ type: "string",
10587
+ alias: ["A", "a"],
10588
+ description: "Show APCA contrast report. Optional: filter by level name or Lc value"
10274
10589
  }
10275
10590
  },
10276
10591
  run({ args }) {
@@ -10510,10 +10825,23 @@ var main = defineCommand({
10510
10825
  colors: formattedShiftedColors
10511
10826
  });
10512
10827
  }
10828
+ const accessibilityEnabled = args.accessibility !== undefined;
10829
+ const accessibilityFilter = accessibilityEnabled ? parseAccessibilityFilter(args.accessibility) : undefined;
10513
10830
  if (outputType === "json") {
10514
- console.log(formatJson(ramps));
10831
+ if (accessibilityEnabled) {
10832
+ const report = generateAccessibilityReport(ramps, accessibilityFilter);
10833
+ const output = { ramps: JSON.parse(formatJson(ramps)).ramps, accessibility: formatAccessibilityJson(report) };
10834
+ console.log(JSON.stringify(output, null, 2));
10835
+ } else {
10836
+ console.log(formatJson(ramps));
10837
+ }
10515
10838
  } else if (outputType === "css") {
10516
- console.log(formatCss2(ramps));
10839
+ let output = formatCss2(ramps);
10840
+ if (accessibilityEnabled) {
10841
+ const report = generateAccessibilityReport(ramps, accessibilityFilter);
10842
+ output += formatAccessibilityCss(report);
10843
+ }
10844
+ console.log(output);
10517
10845
  } else {
10518
10846
  const canShowPreview = args.preview && supportsTruecolor();
10519
10847
  if (args.preview && !canShowPreview) {
@@ -10540,6 +10868,10 @@ var main = defineCommand({
10540
10868
  }
10541
10869
  });
10542
10870
  });
10871
+ if (accessibilityEnabled) {
10872
+ const report = generateAccessibilityReport(ramps, accessibilityFilter);
10873
+ console.log(formatAccessibilityText(report, { preview: canShowPreview }));
10874
+ }
10543
10875
  }
10544
10876
  }
10545
10877
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basiclines/rampa",
3
- "version": "1.1.3",
3
+ "version": "1.3.0",
4
4
  "description": "Generate mathematically accurate color palettes from a base color",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,7 +22,8 @@
22
22
  "build:linux-arm64": "bun build ./src/index.ts --compile --target=bun-linux-arm64 --outfile=./dist/rampa-linux-arm64",
23
23
  "build:windows-x64": "bun build ./src/index.ts --compile --target=bun-windows-x64 --outfile=./dist/rampa-windows-x64.exe",
24
24
  "build:all": "bun run build:darwin-arm64 && bun run build:darwin-x64 && bun run build:linux-x64 && bun run build:linux-arm64 && bun run build:windows-x64",
25
- "release": "bun run scripts/release.ts"
25
+ "release": "bun run scripts/release.ts",
26
+ "eval": "bun run evals/src/runner.ts"
26
27
  },
27
28
  "repository": {
28
29
  "type": "git",
@@ -39,13 +40,16 @@
39
40
  "author": "ismael.fyi",
40
41
  "license": "SEE LICENSE IN LICENSE.md",
41
42
  "dependencies": {
42
- "citty": "^0.1.6",
43
+ "apca-w3": "^0.1.9",
43
44
  "chroma-js": "^3.1.2",
45
+ "citty": "^0.1.6",
44
46
  "culori": "^4.0.1"
45
47
  },
46
48
  "devDependencies": {
49
+ "@github/copilot-sdk": "^0.1.23",
47
50
  "@types/bun": "^1.2.17",
48
51
  "@types/chroma-js": "^3.1.1",
52
+ "picocolors": "^1.1.1",
49
53
  "typescript": "^5.5.3"
50
54
  }
51
55
  }