@sarmal/core 0.29.1 → 0.30.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/dist/auto-init.cjs +72 -31
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +72 -31
- package/dist/auto-init.js.map +1 -1
- package/dist/cli.js +31 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +72 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +72 -31
- package/dist/index.js.map +1 -1
- package/dist/terminal.cjs +33 -4
- package/dist/terminal.cjs.map +1 -1
- package/dist/terminal.d.cts +1 -1
- package/dist/terminal.d.ts +1 -1
- package/dist/terminal.js +33 -4
- package/dist/terminal.js.map +1 -1
- package/package.json +1 -1
- package/skills/core/SKILL.md +1 -1
package/dist/index.cjs
CHANGED
|
@@ -385,6 +385,35 @@ function hexToRgb(hex) {
|
|
|
385
385
|
const n = parseInt(hex.slice(1), 16);
|
|
386
386
|
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
387
387
|
}
|
|
388
|
+
var HEX_3_RE = /^#([0-9a-fA-F]{3})$/;
|
|
389
|
+
var HEX_6_RE = /^#([0-9a-fA-F]{6})$/;
|
|
390
|
+
var HEX_8_RE = /^#([0-9a-fA-F]{8})$/;
|
|
391
|
+
var RGB_RE = /^rgba?\(\s*(-?\d{1,3})\s*,\s*(-?\d{1,3})\s*,\s*(-?\d{1,3})(?:\s*,\s*[\d.]+)?\s*\)$/i;
|
|
392
|
+
function parseColorToRgb(s) {
|
|
393
|
+
const trimmed = s.trim();
|
|
394
|
+
const m3 = HEX_3_RE.exec(trimmed);
|
|
395
|
+
if (m3) {
|
|
396
|
+
const [r, g, b] = m3[1];
|
|
397
|
+
return hexToRgb(`#${r}${r}${g}${g}${b}${b}`);
|
|
398
|
+
}
|
|
399
|
+
const m6 = HEX_6_RE.exec(trimmed);
|
|
400
|
+
if (m6) {
|
|
401
|
+
return hexToRgb(trimmed);
|
|
402
|
+
}
|
|
403
|
+
const m8 = HEX_8_RE.exec(trimmed);
|
|
404
|
+
if (m8) {
|
|
405
|
+
return hexToRgb(`#${trimmed.slice(1, 7)}`);
|
|
406
|
+
}
|
|
407
|
+
const mRgb = RGB_RE.exec(trimmed);
|
|
408
|
+
if (mRgb) {
|
|
409
|
+
return {
|
|
410
|
+
r: Math.max(0, Math.min(255, parseInt(mRgb[1], 10))),
|
|
411
|
+
g: Math.max(0, Math.min(255, parseInt(mRgb[2], 10))),
|
|
412
|
+
b: Math.max(0, Math.min(255, parseInt(mRgb[3], 10)))
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
388
417
|
function srgbByteToLinear(c) {
|
|
389
418
|
const n = c / 255;
|
|
390
419
|
return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
|
|
@@ -444,7 +473,6 @@ function getPaletteColor(palette, position, timeOffset = 0) {
|
|
|
444
473
|
const c2 = hexToRgb(palette[(idx + 1) % palette.length]);
|
|
445
474
|
return lerpOklab(c1, c2, t);
|
|
446
475
|
}
|
|
447
|
-
var HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;
|
|
448
476
|
var TRAIL_STYLES = ["default", "gradient-static", "gradient-animated"];
|
|
449
477
|
var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
450
478
|
"trailColor",
|
|
@@ -477,9 +505,9 @@ function validateRenderOptions(partial) {
|
|
|
477
505
|
}
|
|
478
506
|
function assertTrailColor(value) {
|
|
479
507
|
if (typeof value === "string") {
|
|
480
|
-
if (
|
|
508
|
+
if (parseColorToRgb(value) === null) {
|
|
481
509
|
throw new TypeError(
|
|
482
|
-
`[sarmal] setRenderOptions: trailColor must be a
|
|
510
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got "${value}"`
|
|
483
511
|
);
|
|
484
512
|
}
|
|
485
513
|
return;
|
|
@@ -492,25 +520,25 @@ function assertTrailColor(value) {
|
|
|
492
520
|
}
|
|
493
521
|
for (let i = 0; i < value.length; i++) {
|
|
494
522
|
const entry = value[i];
|
|
495
|
-
if (typeof entry !== "string" ||
|
|
523
|
+
if (typeof entry !== "string" || parseColorToRgb(entry) === null) {
|
|
496
524
|
throw new TypeError(
|
|
497
|
-
`[sarmal] setRenderOptions: trailColor[${i}] must be a
|
|
525
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got ${JSON.stringify(entry)}`
|
|
498
526
|
);
|
|
499
527
|
}
|
|
500
528
|
}
|
|
501
529
|
return;
|
|
502
530
|
}
|
|
503
531
|
throw new TypeError(
|
|
504
|
-
`[sarmal] setRenderOptions: trailColor must be a
|
|
532
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or an array of color strings, got ${JSON.stringify(value)}`
|
|
505
533
|
);
|
|
506
534
|
}
|
|
507
535
|
function assertHeadColor(value) {
|
|
508
536
|
if (value === null) {
|
|
509
537
|
return;
|
|
510
538
|
}
|
|
511
|
-
if (typeof value !== "string" ||
|
|
539
|
+
if (typeof value !== "string" || parseColorToRgb(value) === null) {
|
|
512
540
|
throw new TypeError(
|
|
513
|
-
`[sarmal] setRenderOptions: headColor must be a
|
|
541
|
+
`[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or null, got ${JSON.stringify(value)}`
|
|
514
542
|
);
|
|
515
543
|
}
|
|
516
544
|
}
|
|
@@ -518,9 +546,9 @@ function assertSkeletonColor(value) {
|
|
|
518
546
|
if (value === "transparent") {
|
|
519
547
|
return;
|
|
520
548
|
}
|
|
521
|
-
if (typeof value !== "string" ||
|
|
549
|
+
if (typeof value !== "string" || parseColorToRgb(value) === null) {
|
|
522
550
|
throw new TypeError(
|
|
523
|
-
`[sarmal] setRenderOptions: skeletonColor must be a
|
|
551
|
+
`[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or "transparent", got ${JSON.stringify(value)}`
|
|
524
552
|
);
|
|
525
553
|
}
|
|
526
554
|
}
|
|
@@ -555,7 +583,7 @@ function resolveHeadColor(trailColor, trailStyle) {
|
|
|
555
583
|
}
|
|
556
584
|
const palette = resolveTrailPalette(trailColor);
|
|
557
585
|
const last = palette[palette.length - 1];
|
|
558
|
-
const { r, g, b } =
|
|
586
|
+
const { r, g, b } = parseColorToRgb(last);
|
|
559
587
|
return `rgb(${r},${g},${b})`;
|
|
560
588
|
}
|
|
561
589
|
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
@@ -575,9 +603,9 @@ function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
|
575
603
|
// src/renderer.ts
|
|
576
604
|
var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160));
|
|
577
605
|
var WHITE_HEX = "#ffffff";
|
|
578
|
-
function
|
|
579
|
-
const
|
|
580
|
-
return `${
|
|
606
|
+
function colorToRgbComponents(color) {
|
|
607
|
+
const c = parseColorToRgb(color);
|
|
608
|
+
return `${c.r},${c.g},${c.b}`;
|
|
581
609
|
}
|
|
582
610
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
583
611
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -597,7 +625,7 @@ function createRenderer(options) {
|
|
|
597
625
|
let skeletonColor = options.skeletonColor ?? WHITE_HEX;
|
|
598
626
|
let userHeadColor = options.headColor ?? null;
|
|
599
627
|
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
600
|
-
let trailSolidRgb =
|
|
628
|
+
let trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
601
629
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
602
630
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
603
631
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
@@ -642,7 +670,7 @@ function createRenderer(options) {
|
|
|
642
670
|
skeletonCanvas = new OffscreenCanvas(canvas.width, canvas.height);
|
|
643
671
|
const skeletonCtx = skeletonCanvas.getContext("2d");
|
|
644
672
|
skeletonCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
645
|
-
skeletonCtx.strokeStyle = `rgba(${
|
|
673
|
+
skeletonCtx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
646
674
|
skeletonCtx.lineWidth = 1.5;
|
|
647
675
|
skeletonCtx.beginPath();
|
|
648
676
|
const first = skeleton[0];
|
|
@@ -657,7 +685,7 @@ function createRenderer(options) {
|
|
|
657
685
|
if (pts.length < 2) {
|
|
658
686
|
return;
|
|
659
687
|
}
|
|
660
|
-
ctx.strokeStyle = `rgba(${
|
|
688
|
+
ctx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${opacity})`;
|
|
661
689
|
ctx.lineWidth = 1.5;
|
|
662
690
|
ctx.beginPath();
|
|
663
691
|
ctx.moveTo(pts[0].x * scale + offsetX, pts[0].y * scale + offsetY);
|
|
@@ -678,7 +706,7 @@ function createRenderer(options) {
|
|
|
678
706
|
if (skeleton.length < 2) {
|
|
679
707
|
return;
|
|
680
708
|
}
|
|
681
|
-
ctx.strokeStyle = `rgba(${
|
|
709
|
+
ctx.strokeStyle = `rgba(${colorToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
682
710
|
ctx.lineWidth = 1.5;
|
|
683
711
|
ctx.beginPath();
|
|
684
712
|
const first = skeleton[0];
|
|
@@ -755,7 +783,7 @@ function createRenderer(options) {
|
|
|
755
783
|
morphReject = null;
|
|
756
784
|
morphAlpha = 0;
|
|
757
785
|
skeleton = engine.getSarmalSkeleton();
|
|
758
|
-
if (!engine.isLiveSkeleton) {
|
|
786
|
+
if (!engine.isLiveSkeleton && skeletonColor !== "transparent") {
|
|
759
787
|
buildSkeletonCanvas();
|
|
760
788
|
}
|
|
761
789
|
}
|
|
@@ -781,7 +809,7 @@ function createRenderer(options) {
|
|
|
781
809
|
}
|
|
782
810
|
skeleton = engine.getSarmalSkeleton();
|
|
783
811
|
calculateBoundaries();
|
|
784
|
-
if (!engine.isLiveSkeleton) {
|
|
812
|
+
if (!engine.isLiveSkeleton && skeletonColor !== "transparent") {
|
|
785
813
|
buildSkeletonCanvas();
|
|
786
814
|
}
|
|
787
815
|
if (options.initialPhase !== void 0) {
|
|
@@ -843,7 +871,7 @@ function createRenderer(options) {
|
|
|
843
871
|
validateRenderOptions(partial);
|
|
844
872
|
if (partial.trailColor !== void 0) {
|
|
845
873
|
trailColor = partial.trailColor;
|
|
846
|
-
trailSolidRgb =
|
|
874
|
+
trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
847
875
|
trailPalette = resolveTrailPalette(trailColor);
|
|
848
876
|
}
|
|
849
877
|
if (partial.skeletonColor !== void 0) {
|
|
@@ -927,6 +955,10 @@ function sampleCurveSkeleton(curveDef) {
|
|
|
927
955
|
function el(tag) {
|
|
928
956
|
return document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
929
957
|
}
|
|
958
|
+
function colorToRgbAttr(color) {
|
|
959
|
+
const c = parseColorToRgb(color);
|
|
960
|
+
return `rgb(${c.r},${c.g},${c.b})`;
|
|
961
|
+
}
|
|
930
962
|
function createSVGRenderer(options) {
|
|
931
963
|
const { container, engine } = options;
|
|
932
964
|
const poolSize = engine.trailLength;
|
|
@@ -941,7 +973,7 @@ function createSVGRenderer(options) {
|
|
|
941
973
|
let userHeadColor = options.headColor ?? null;
|
|
942
974
|
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
943
975
|
let headRadius;
|
|
944
|
-
let trailSolid = resolveTrailMainColor(trailColor);
|
|
976
|
+
let trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
945
977
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
946
978
|
const ariaLabel = options.ariaLabel ?? "Loading";
|
|
947
979
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
@@ -965,7 +997,10 @@ function createSVGRenderer(options) {
|
|
|
965
997
|
const skeletonPath = el("path");
|
|
966
998
|
skeletonPath.setAttribute("data-sarmal-role", "skeleton");
|
|
967
999
|
skeletonPath.setAttribute("fill", "none");
|
|
968
|
-
skeletonPath.setAttribute(
|
|
1000
|
+
skeletonPath.setAttribute(
|
|
1001
|
+
"stroke",
|
|
1002
|
+
skeletonColor === "transparent" ? "transparent" : colorToRgbAttr(skeletonColor)
|
|
1003
|
+
);
|
|
969
1004
|
skeletonPath.setAttribute("stroke-opacity", String(DEFAULT_SKELETON_OPACITY));
|
|
970
1005
|
skeletonPath.setAttribute("stroke-width", svgSkeletonStrokeWidth);
|
|
971
1006
|
if (skeletonColor === "transparent") {
|
|
@@ -974,13 +1009,19 @@ function createSVGRenderer(options) {
|
|
|
974
1009
|
group.appendChild(skeletonPath);
|
|
975
1010
|
const skeletonPathA = el("path");
|
|
976
1011
|
skeletonPathA.setAttribute("fill", "none");
|
|
977
|
-
skeletonPathA.setAttribute(
|
|
1012
|
+
skeletonPathA.setAttribute(
|
|
1013
|
+
"stroke",
|
|
1014
|
+
skeletonColor === "transparent" ? "transparent" : colorToRgbAttr(skeletonColor)
|
|
1015
|
+
);
|
|
978
1016
|
skeletonPathA.setAttribute("stroke-width", svgSkeletonStrokeWidth);
|
|
979
1017
|
skeletonPathA.setAttribute("visibility", "hidden");
|
|
980
1018
|
group.appendChild(skeletonPathA);
|
|
981
1019
|
const skeletonPathB = el("path");
|
|
982
1020
|
skeletonPathB.setAttribute("fill", "none");
|
|
983
|
-
skeletonPathB.setAttribute(
|
|
1021
|
+
skeletonPathB.setAttribute(
|
|
1022
|
+
"stroke",
|
|
1023
|
+
skeletonColor === "transparent" ? "transparent" : colorToRgbAttr(skeletonColor)
|
|
1024
|
+
);
|
|
984
1025
|
skeletonPathB.setAttribute("stroke-width", svgSkeletonStrokeWidth);
|
|
985
1026
|
skeletonPathB.setAttribute("visibility", "hidden");
|
|
986
1027
|
group.appendChild(skeletonPathB);
|
|
@@ -995,7 +1036,7 @@ function createSVGRenderer(options) {
|
|
|
995
1036
|
}
|
|
996
1037
|
const headCircle = el("circle");
|
|
997
1038
|
headCircle.setAttribute("data-sarmal-role", "head");
|
|
998
|
-
headCircle.setAttribute("fill", headColor);
|
|
1039
|
+
headCircle.setAttribute("fill", colorToRgbAttr(headColor));
|
|
999
1040
|
headCircle.setAttribute("r", String(headRadius));
|
|
1000
1041
|
group.appendChild(headCircle);
|
|
1001
1042
|
container.appendChild(group);
|
|
@@ -1198,7 +1239,7 @@ function createSVGRenderer(options) {
|
|
|
1198
1239
|
const prevTrailStyle = trailStyle;
|
|
1199
1240
|
if (partial.trailColor !== void 0) {
|
|
1200
1241
|
trailColor = partial.trailColor;
|
|
1201
|
-
trailSolid = resolveTrailMainColor(trailColor);
|
|
1242
|
+
trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
1202
1243
|
trailPalette = resolveTrailPalette(trailColor);
|
|
1203
1244
|
if (trailStyle === "default") {
|
|
1204
1245
|
for (const p of trailPaths) {
|
|
@@ -1211,10 +1252,10 @@ function createSVGRenderer(options) {
|
|
|
1211
1252
|
if (skeletonColor === "transparent") {
|
|
1212
1253
|
skeletonPath.setAttribute("visibility", "hidden");
|
|
1213
1254
|
} else {
|
|
1214
|
-
skeletonPath.setAttribute("stroke", skeletonColor);
|
|
1255
|
+
skeletonPath.setAttribute("stroke", colorToRgbAttr(skeletonColor));
|
|
1215
1256
|
skeletonPath.removeAttribute("visibility");
|
|
1216
|
-
skeletonPathA.setAttribute("stroke", skeletonColor);
|
|
1217
|
-
skeletonPathB.setAttribute("stroke", skeletonColor);
|
|
1257
|
+
skeletonPathA.setAttribute("stroke", colorToRgbAttr(skeletonColor));
|
|
1258
|
+
skeletonPathB.setAttribute("stroke", colorToRgbAttr(skeletonColor));
|
|
1218
1259
|
}
|
|
1219
1260
|
}
|
|
1220
1261
|
if (partial.trailStyle !== void 0) {
|
|
@@ -1237,7 +1278,7 @@ function createSVGRenderer(options) {
|
|
|
1237
1278
|
} else {
|
|
1238
1279
|
headColor = userHeadColor;
|
|
1239
1280
|
}
|
|
1240
|
-
headCircle.setAttribute("fill", headColor);
|
|
1281
|
+
headCircle.setAttribute("fill", colorToRgbAttr(headColor));
|
|
1241
1282
|
if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
|
|
1242
1283
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
1243
1284
|
}
|