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