@socketsecurity/lib 5.26.0 → 5.26.1

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 (147) hide show
  1. package/CHANGELOG.md +345 -1185
  2. package/README.md +1 -1
  3. package/dist/abort.js +7 -6
  4. package/dist/agent.js +16 -15
  5. package/dist/ansi.js +3 -2
  6. package/dist/archives.js +18 -17
  7. package/dist/argv/flags.js +29 -28
  8. package/dist/argv/parse.js +4 -3
  9. package/dist/arrays.js +3 -2
  10. package/dist/bin.js +12 -11
  11. package/dist/cacache.js +16 -11
  12. package/dist/cache-with-ttl.js +26 -21
  13. package/dist/colors.js +2 -1
  14. package/dist/constants/licenses.js +2 -1
  15. package/dist/constants/lifecycle-script-names.js +2 -1
  16. package/dist/constants/maintained-node-versions.js +2 -1
  17. package/dist/constants/node.js +4 -3
  18. package/dist/constants/package-default-socket-categories.js +2 -1
  19. package/dist/constants/packages.js +4 -3
  20. package/dist/constants/socket.js +1 -1
  21. package/dist/cover/code.js +9 -8
  22. package/dist/cover/formatters.js +12 -11
  23. package/dist/cover/type.js +5 -4
  24. package/dist/crypto.d.ts +36 -0
  25. package/dist/{effects/ultra.js → crypto.js} +33 -37
  26. package/dist/debug.js +12 -15
  27. package/dist/dlx/arborist.js +10 -9
  28. package/dist/dlx/binary.js +27 -24
  29. package/dist/dlx/cache.js +2 -10
  30. package/dist/dlx/detect.js +6 -5
  31. package/dist/dlx/integrity.js +13 -11
  32. package/dist/dlx/lockfile.js +7 -6
  33. package/dist/dlx/manifest.js +6 -5
  34. package/dist/dlx/package.js +17 -16
  35. package/dist/dlx/packages.js +6 -5
  36. package/dist/dlx/paths.d.ts +1 -1
  37. package/dist/dlx/paths.js +2 -1
  38. package/dist/effects/pulse-frames.js +4 -3
  39. package/dist/effects/shimmer-keyframes.d.ts +62 -0
  40. package/dist/effects/shimmer-keyframes.js +55 -0
  41. package/dist/effects/shimmer-terminal.d.ts +66 -0
  42. package/dist/effects/shimmer-terminal.js +57 -0
  43. package/dist/effects/shimmer.d.ts +293 -0
  44. package/dist/effects/shimmer.js +180 -0
  45. package/dist/env/rewire.js +4 -3
  46. package/dist/env.js +5 -4
  47. package/dist/errors.js +1 -1
  48. package/dist/external/@npmcli/package-json/lib/read-package.js +10 -10
  49. package/dist/external/@npmcli/package-json.js +372 -372
  50. package/dist/external/@npmcli/promise-spawn.js +24 -24
  51. package/dist/external/@socketregistry/packageurl-js.js +19 -18
  52. package/dist/external/@socketregistry/yocto-spinner.js +4 -3
  53. package/dist/external/@yarnpkg/extensions.js +2 -1
  54. package/dist/external/adm-zip.js +70 -70
  55. package/dist/external/debug.js +22 -22
  56. package/dist/external/external-pack.js +45 -45
  57. package/dist/external/fast-sort.js +5 -5
  58. package/dist/external/libnpmexec.js +4 -3
  59. package/dist/external/npm-pack.js +369 -369
  60. package/dist/external/p-map.js +9 -9
  61. package/dist/external/pico-pack.js +190 -190
  62. package/dist/external/pony-cause.js +2 -1
  63. package/dist/external/spdx-pack.js +11 -10
  64. package/dist/external/tar-fs.js +58 -58
  65. package/dist/external/which.js +13 -13
  66. package/dist/external/yargs-parser.js +71 -71
  67. package/dist/fs.js +19 -23
  68. package/dist/git.js +14 -13
  69. package/dist/github.d.ts +34 -0
  70. package/dist/github.js +248 -23
  71. package/dist/globs.d.ts +20 -0
  72. package/dist/globs.js +134 -25
  73. package/dist/http-request.d.ts +4 -3
  74. package/dist/http-request.js +39 -32
  75. package/dist/ipc-cli.js +2 -1
  76. package/dist/ipc.js +5 -4
  77. package/dist/json/edit.js +4 -3
  78. package/dist/json/format.js +3 -2
  79. package/dist/json/parse.js +7 -6
  80. package/dist/links.js +2 -1
  81. package/dist/logger.js +21 -14
  82. package/dist/memoization.js +16 -15
  83. package/dist/objects.js +2 -2
  84. package/dist/packages/edit.js +8 -7
  85. package/dist/packages/exports.js +17 -16
  86. package/dist/packages/isolation.js +20 -13
  87. package/dist/packages/licenses.js +6 -3
  88. package/dist/packages/manifest.js +2 -1
  89. package/dist/packages/normalize.js +8 -4
  90. package/dist/packages/operations.js +5 -4
  91. package/dist/packages/provenance.js +7 -6
  92. package/dist/packages/specs.js +2 -1
  93. package/dist/packages/validation.js +2 -1
  94. package/dist/paths/normalize.js +32 -40
  95. package/dist/paths/packages.js +2 -1
  96. package/dist/paths/rewire.js +3 -2
  97. package/dist/performance.js +19 -18
  98. package/dist/primordials.d.ts +9 -0
  99. package/dist/primordials.js +17 -0
  100. package/dist/process-lock.js +14 -13
  101. package/dist/promise-queue.js +17 -9
  102. package/dist/promises.d.ts +29 -6
  103. package/dist/promises.js +19 -15
  104. package/dist/regexps.js +9 -8
  105. package/dist/releases/github-api.d.ts +56 -0
  106. package/dist/releases/github-api.js +275 -0
  107. package/dist/releases/github-archives.d.ts +60 -0
  108. package/dist/releases/github-archives.js +136 -0
  109. package/dist/releases/github-assets.d.ts +21 -0
  110. package/dist/releases/github-assets.js +52 -0
  111. package/dist/releases/github-auth.d.ts +16 -0
  112. package/dist/releases/github-auth.js +51 -0
  113. package/dist/releases/github-downloads.d.ts +42 -0
  114. package/dist/releases/github-downloads.js +155 -0
  115. package/dist/releases/github-types.d.ts +66 -0
  116. package/dist/{effects/types.js → releases/github-types.js} +2 -2
  117. package/dist/releases/socket-btm.d.ts +1 -1
  118. package/dist/releases/socket-btm.js +17 -17
  119. package/dist/schema/parse.js +2 -1
  120. package/dist/schema/validate.js +6 -5
  121. package/dist/shadow.js +2 -1
  122. package/dist/signal-exit.js +2 -2
  123. package/dist/spawn.js +45 -35
  124. package/dist/spinner.d.ts +13 -6
  125. package/dist/spinner.js +75 -57
  126. package/dist/ssri.js +8 -7
  127. package/dist/stdio/footer.js +13 -12
  128. package/dist/stdio/header.js +5 -4
  129. package/dist/stdio/progress.js +13 -12
  130. package/dist/strings.js +19 -18
  131. package/dist/suppress-warnings.js +2 -2
  132. package/dist/tables.js +16 -13
  133. package/dist/temporary-executor.js +2 -1
  134. package/dist/themes/context.js +2 -1
  135. package/dist/themes/types.d.ts +1 -1
  136. package/dist/themes/utils.d.ts +8 -3
  137. package/dist/themes/utils.js +29 -5
  138. package/dist/url.js +4 -3
  139. package/package.json +44 -20
  140. package/dist/effects/text-shimmer.d.ts +0 -58
  141. package/dist/effects/text-shimmer.js +0 -192
  142. package/dist/effects/types.d.ts +0 -47
  143. package/dist/effects/ultra.d.ts +0 -22
  144. package/dist/releases/github.d.ts +0 -234
  145. package/dist/releases/github.js +0 -417
  146. package/dist/themes/index.d.ts +0 -49
  147. package/dist/themes/index.js +0 -60
@@ -44,7 +44,7 @@ export declare function getDlxPackageNodeModulesDir(packageName: string): string
44
44
  *
45
45
  * @example
46
46
  * ```typescript
47
- * isInSocketDlx('/home/user/.socket/_dlx/abc123/bin/socket') // true
47
+ * isInSocketDlx('/home/<user>/.socket/_dlx/abc123/bin/socket') // true
48
48
  * isInSocketDlx('/usr/local/bin/socket') // false
49
49
  * isInSocketDlx(process.argv[0]) // Check if current binary is in DLX
50
50
  * ```
package/dist/dlx/paths.js CHANGED
@@ -29,6 +29,7 @@ __export(paths_exports, {
29
29
  module.exports = __toCommonJS(paths_exports);
30
30
  var import_normalize = require("../paths/normalize");
31
31
  var import_socket = require("../paths/socket");
32
+ var import_primordials = require("../primordials");
32
33
  let _path;
33
34
  // @__NO_SIDE_EFFECTS__
34
35
  function getPath() {
@@ -64,7 +65,7 @@ function isInSocketDlx(filePath) {
64
65
  const path = /* @__PURE__ */ getPath();
65
66
  const dlxDir = (0, import_normalize.normalizePath)((0, import_socket.getSocketDlxDir)());
66
67
  const absolutePath = (0, import_normalize.normalizePath)(path.resolve(filePath));
67
- return absolutePath.startsWith(`${dlxDir}/`);
68
+ return (0, import_primordials.StringPrototypeStartsWith)(absolutePath, `${dlxDir}/`);
68
69
  }
69
70
  // Annotate the CommonJS export names for ESM import in node:
70
71
  0 && (module.exports = {
@@ -23,12 +23,13 @@ __export(pulse_frames_exports, {
23
23
  generateSocketSpinnerFrames: () => generateSocketSpinnerFrames
24
24
  });
25
25
  module.exports = __toCommonJS(pulse_frames_exports);
26
+ var import_ansi = require("../ansi");
26
27
  function generateSocketSpinnerFrames(options) {
27
28
  const opts = { __proto__: null, ...options };
28
29
  const interval = opts.interval ?? 50;
29
- const bold = "\x1B[1m";
30
- const dim = "\x1B[2m";
31
- const reset = "\x1B[0m";
30
+ const bold = import_ansi.ANSI_BOLD;
31
+ const dim = import_ansi.ANSI_DIM;
32
+ const reset = import_ansi.ANSI_RESET;
32
33
  const lightning = "\u26A1\uFE0E";
33
34
  const starFilled = "\u2726\uFE0E ";
34
35
  const starOutline = "\u2727\uFE0E ";
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @fileoverview SVG keyframe batcher for the shimmer engine.
3
+ *
4
+ * Pre-renders N frames of the engine and emits per-character keyTimes /
5
+ * values arrays suitable for SVG SMIL `<animate>` elements. The output is
6
+ * deduplicated (consecutive identical colors collapse to a single
7
+ * keyframe) and closed with a `t=1` anchor so the animation loops cleanly.
8
+ *
9
+ * Use with `calcMode="discrete"` to reproduce the engine's output exactly
10
+ * — no SMIL interpolation between frames, each frame holds until the
11
+ * next changes.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { configToSpec } from '@socketsecurity/lib/effects/shimmer'
16
+ * import { toShimmerKeyframes } from '@socketsecurity/lib/effects/shimmer-keyframes'
17
+ * const spec = configToSpec({ color: RAINBOW_GRADIENT, dir: 'ltr' }, 10)
18
+ * const tracks = toShimmerKeyframes(spec, 10, 60)
19
+ * // Emit one <animate> per char in your SVG:
20
+ * // <animate attributeName="fill" calcMode="discrete"
21
+ * // keyTimes={tracks[i].times.join(';')}
22
+ * // values={tracks[i].values.join(';')}
23
+ * // dur="3s" repeatCount="indefinite" />
24
+ * ```
25
+ */
26
+ import { type ShimmerSpec } from './shimmer';
27
+ /**
28
+ * Keyframe track for a single character. `times[i]` is in [0, 1] and
29
+ * pairs with `values[i]` (an `rgb(R,G,B)` string). Use directly as SMIL
30
+ * `<animate>` attributes:
31
+ *
32
+ * ```jsx
33
+ * <animate
34
+ * keyTimes={track.times.join(';')}
35
+ * values={track.values.join(';')}
36
+ * calcMode="discrete"
37
+ * />
38
+ * ```
39
+ */
40
+ export type Keyframes = {
41
+ /** Normalized timestamps in [0, 1], monotonically non-decreasing. */
42
+ readonly times: readonly number[];
43
+ /** `rgb(R,G,B)` color strings, paired by index with `times`. */
44
+ readonly values: readonly string[];
45
+ };
46
+ /**
47
+ * Render N frames of a shimmer spec into per-character keyframe tracks.
48
+ *
49
+ * Output is one {@link Keyframes} object per char. Consecutive identical
50
+ * colors collapse — only the first occurrence emits a keyframe, the rest
51
+ * are implicit (SMIL holds the previous value). A final keyframe at `t=1`
52
+ * closes the loop with the same value as `t=0` so playback wraps cleanly.
53
+ *
54
+ * Use with `calcMode="discrete"` to reproduce the engine's per-frame
55
+ * output exactly (no SMIL interpolation between frames).
56
+ *
57
+ * @param spec functional shimmer specification
58
+ * @param textLength number of chars to colorize
59
+ * @param frames total frame count to bake into the loop
60
+ * @returns one Keyframes track per char index, in order
61
+ */
62
+ export declare function toShimmerKeyframes(spec: ShimmerSpec, textLength: number, frames: number): Keyframes[];
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /* Socket Lib - Built with esbuild */
3
+ "use strict";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+ var shimmer_keyframes_exports = {};
22
+ __export(shimmer_keyframes_exports, {
23
+ toShimmerKeyframes: () => toShimmerKeyframes
24
+ });
25
+ module.exports = __toCommonJS(shimmer_keyframes_exports);
26
+ var import_shimmer = require("./shimmer");
27
+ function toShimmerKeyframes(spec, textLength, frames) {
28
+ const tracks = [];
29
+ for (let i = 0; i < textLength; i++) {
30
+ tracks.push({ times: [], values: [] });
31
+ }
32
+ for (let f = 0; f < frames; f++) {
33
+ const t = f / frames;
34
+ const colors = (0, import_shimmer.frameColors)(spec, textLength, f);
35
+ for (let i = 0; i < textLength; i++) {
36
+ const c = colors[i];
37
+ const v = `rgb(${c[0]},${c[1]},${c[2]})`;
38
+ const track = tracks[i];
39
+ if (track.values[track.values.length - 1] !== v) {
40
+ track.times.push(t);
41
+ track.values.push(v);
42
+ }
43
+ }
44
+ }
45
+ for (let i = 0; i < textLength; i++) {
46
+ const track = tracks[i];
47
+ track.times.push(1);
48
+ track.values.push(track.values[0] ?? "rgb(0,0,0)");
49
+ }
50
+ return tracks;
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ toShimmerKeyframes
55
+ });
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @fileoverview Terminal renderer for the shimmer engine.
3
+ *
4
+ * Turns the engine's `RGB[]` output into a single ANSI-escaped string ready
5
+ * to write to stdout/stderr. Uses 24-bit truecolor escape sequences
6
+ * (`\x1b[38;2;R;G;Bm`) which most modern terminals (iTerm2, Terminal.app,
7
+ * Windows Terminal, Alacritty, Ghostty, kitty, gnome-terminal) support
8
+ * natively. Terminals that lack truecolor (basic `xterm`, some serial
9
+ * consoles) will display the raw escape codes — call sites that need to
10
+ * support those terminals should fall back to {@link colorsToAnsi}'s
11
+ * "no colors" path or skip rendering entirely.
12
+ *
13
+ * The high-level {@link renderFrame} convenience runs the full pipeline
14
+ * (engine → ANSI) in one call. {@link colorsToAnsi} is the lower-level
15
+ * helper for when you already have an `RGB[]` from {@link frameColors}.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { configToSpec } from '@socketsecurity/lib/effects/shimmer'
20
+ * import { renderFrame } from '@socketsecurity/lib/effects/shimmer-terminal'
21
+ * const spec = configToSpec({ color: [140, 82, 255], dir: 'ltr' }, 'Loading'.length)
22
+ * process.stdout.write(renderFrame(spec, 'Loading', frame))
23
+ * ```
24
+ */
25
+ import { ANSI_RESET } from '../ansi';
26
+ import { type RGB, type ShimmerSpec } from './shimmer';
27
+ /**
28
+ * ANSI "reset all attributes" sequence. Re-exported from `../ansi` for
29
+ * convenience so callers don't need a separate import for the canonical
30
+ * value. Identical to `ANSI_RESET` in `@socketsecurity/lib/ansi`.
31
+ */
32
+ export { ANSI_RESET };
33
+ /**
34
+ * Build the 24-bit truecolor foreground escape for an RGB tuple. Returns
35
+ * `\x1b[38;2;R;G;Bm`. Exported so callers building ANSI by hand can use
36
+ * the same helper.
37
+ */
38
+ export declare function ansiTruecolor([r, g, b]: RGB): string;
39
+ /**
40
+ * Wrap each char of `text` in a 24-bit truecolor ANSI escape using the
41
+ * matching color from `colors`. Each char is followed by an ANSI reset so
42
+ * adjacent uncolored output isn't tinted.
43
+ *
44
+ * Caller is responsible for grapheme segmentation if the text contains
45
+ * complex graphemes (combining marks, ZWJ sequences). This function uses
46
+ * spread iteration which handles BMP code points and surrogate pairs but
47
+ * treats each grapheme cluster as multiple "chars."
48
+ *
49
+ * If `colors.length` is shorter than the text's char count, surplus chars
50
+ * are emitted without color (uncolored tail).
51
+ *
52
+ * @param text input string to color
53
+ * @param colors per-char colors; index `i` colors char `i`
54
+ * @returns ANSI-escaped string
55
+ */
56
+ export declare function colorsToAnsi(text: string, colors: readonly RGB[]): string;
57
+ /**
58
+ * Render a single shimmer frame as ANSI-escaped text. Convenience wrapper
59
+ * over {@link frameColors} + {@link colorsToAnsi} for callers that don't
60
+ * need the intermediate `RGB[]`.
61
+ *
62
+ * @param spec functional shimmer specification (see {@link ShimmerSpec})
63
+ * @param text the string to colorize
64
+ * @param frame caller-controlled frame counter
65
+ */
66
+ export declare function renderFrame(spec: ShimmerSpec, text: string, frame: number): string;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /* Socket Lib - Built with esbuild */
3
+ "use strict";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+ var shimmer_terminal_exports = {};
22
+ __export(shimmer_terminal_exports, {
23
+ ANSI_RESET: () => import_ansi.ANSI_RESET,
24
+ ansiTruecolor: () => ansiTruecolor,
25
+ colorsToAnsi: () => colorsToAnsi,
26
+ renderFrame: () => renderFrame
27
+ });
28
+ module.exports = __toCommonJS(shimmer_terminal_exports);
29
+ var import_ansi = require("../ansi");
30
+ var import_shimmer = require("./shimmer");
31
+ function ansiTruecolor([r, g, b]) {
32
+ return `\x1B[38;2;${r};${g};${b}m`;
33
+ }
34
+ function colorsToAnsi(text, colors) {
35
+ const chars = [...text];
36
+ let out = "";
37
+ for (let i = 0; i < chars.length; i++) {
38
+ const c = colors[i];
39
+ if (c === void 0) {
40
+ out += chars[i];
41
+ continue;
42
+ }
43
+ out += `${ansiTruecolor(c)}${chars[i]}${import_ansi.ANSI_RESET}`;
44
+ }
45
+ return out;
46
+ }
47
+ function renderFrame(spec, text, frame) {
48
+ const chars = [...text];
49
+ return colorsToAnsi(text, (0, import_shimmer.frameColors)(spec, chars.length, frame));
50
+ }
51
+ // Annotate the CommonJS export names for ESM import in node:
52
+ 0 && (module.exports = {
53
+ ANSI_RESET,
54
+ ansiTruecolor,
55
+ colorsToAnsi,
56
+ renderFrame
57
+ });
@@ -0,0 +1,293 @@
1
+ /**
2
+ * @fileoverview Shimmer animation engine — pure functions, zero deps.
3
+ *
4
+ * Animates a "wave" of color sweeping across a string. Designed for
5
+ * terminal spinners but the engine output is just `RGB[]`, so adapters
6
+ * can render to ANSI, SVG keyframes, Ink components, or anything else.
7
+ *
8
+ * The engine is one function: `frameColors(spec, length, frame) → RGB[]`.
9
+ * It is pure — same inputs produce the same output, no shared state.
10
+ *
11
+ * A {@link ShimmerSpec} bundles three orthogonal pieces:
12
+ *
13
+ * 1. `positionAt(frame)` — the wave's center at frame N (in char units;
14
+ * negative = off-screen left, > textLength = off-screen right).
15
+ * Built-ins: {@link ltrSweep}, {@link rtlSweep},
16
+ * {@link bidirectionalSweep}, {@link randomSweep}, {@link noSweep}.
17
+ *
18
+ * 2. `kernel(signedDistance, ctx)` — given a char's signed distance from
19
+ * the wave center, produce its color. Built-ins: {@link blockKernel}
20
+ * (hard on/off) and {@link smoothKernel} (soft glow).
21
+ *
22
+ * 3. `baseColor(i)` / `highlightColor(i)` — per-char palette anchors fed
23
+ * to the kernel as `ctx.baseColor` and `ctx.highlightColor`. Build
24
+ * these with {@link solidColor} (one color for every char) or
25
+ * {@link gradient} (cycle through a palette).
26
+ *
27
+ * Most callers don't build a spec by hand. {@link configToSpec} translates
28
+ * the flat {@link ShimmerConfig} (`{ color, dir, speed, … }`) into a spec
29
+ * using sensible defaults. The spinner uses this internally.
30
+ *
31
+ * Adapters in `shimmer-terminal.ts` and `shimmer-keyframes.ts` consume the
32
+ * engine's `RGB[]` output and render it to ANSI escape sequences or SVG
33
+ * SMIL keyframes respectively.
34
+ *
35
+ * @example Smooth socket-lib-style shimmer over a single color:
36
+ * ```ts
37
+ * import { configToSpec, frameColors } from '@socketsecurity/lib/effects/shimmer'
38
+ * const spec = configToSpec({ color: [140, 82, 255], dir: 'ltr' }, 'Loading'.length)
39
+ * const colorsAtFrame0 = frameColors(spec, 7, 0)
40
+ * ```
41
+ *
42
+ * @example Discrete claude-code-style shimmer with a rainbow gradient:
43
+ * ```ts
44
+ * import { configToSpec } from '@socketsecurity/lib/effects/shimmer'
45
+ * import { RAINBOW_GRADIENT } from '@socketsecurity/lib/themes/utils'
46
+ * const spec = configToSpec(
47
+ * { color: RAINBOW_GRADIENT, dir: 'ltr', kernel: 'block' },
48
+ * 'ultrathink'.length,
49
+ * )
50
+ * ```
51
+ */
52
+ /**
53
+ * RGB color tuple. Each channel is 0-255.
54
+ */
55
+ export type RGB = readonly [r: number, g: number, b: number];
56
+ /**
57
+ * Ordered palette of RGB colors. Indexed via `i % length` in
58
+ * {@link gradient} so palettes shorter than the text wrap.
59
+ */
60
+ export type Palette = readonly RGB[];
61
+ /**
62
+ * Direction the wave sweeps.
63
+ *
64
+ * - `'ltr'` — wave moves left-to-right, restarts at left.
65
+ * - `'rtl'` — wave moves right-to-left, restarts at right.
66
+ * - `'bi'` — alternates LTR and RTL each cycle.
67
+ * - `'random'` — re-rolls direction at each cycle boundary.
68
+ * - `'none'` — wave never appears (every char shows base color).
69
+ */
70
+ export type ShimmerDirection = 'ltr' | 'rtl' | 'bi' | 'random' | 'none';
71
+ /**
72
+ * Context passed to a {@link Kernel} on each invocation. Holds the per-char
73
+ * base and highlight colors so the kernel can blend between them.
74
+ */
75
+ export type KernelContext = {
76
+ /** Color this char shows when the wave is far away. */
77
+ readonly baseColor: RGB;
78
+ /** Color this char shows when the wave is centered on it. */
79
+ readonly highlightColor: RGB;
80
+ };
81
+ /**
82
+ * A {@link Kernel} maps a char's signed distance from the wave center to
83
+ * a color. Negative distance = wave hasn't reached this char yet; positive
84
+ * distance = wave has passed it.
85
+ */
86
+ export type Kernel = (signedDistance: number, ctx: KernelContext) => RGB;
87
+ /**
88
+ * Functional shimmer specification — the full engine input. Built up from
89
+ * orthogonal pieces (position generator, kernel, palette functions) so any
90
+ * piece can be replaced independently.
91
+ */
92
+ export type ShimmerSpec = {
93
+ /** Wave-center position at frame N. */
94
+ readonly positionAt: (frame: number) => number;
95
+ /** Maps wave distance + per-char palette context to a color. */
96
+ readonly kernel: Kernel;
97
+ /** Per-char base color (when the wave is far away). */
98
+ readonly baseColor: (charIndex: number) => RGB;
99
+ /** Per-char highlight color (when the wave is on the char). */
100
+ readonly highlightColor: (charIndex: number) => RGB;
101
+ };
102
+ /**
103
+ * User-facing flat shimmer config. Translated to a {@link ShimmerSpec} by
104
+ * {@link configToSpec}. Pass a `ShimmerSpec` directly when you need full
105
+ * control over the wave's curve.
106
+ */
107
+ export type ShimmerConfig = {
108
+ /**
109
+ * Base color (single RGB) or per-char palette (array of RGB).
110
+ * @default [140, 82, 255] — Socket purple
111
+ */
112
+ readonly color?: RGB | Palette | undefined;
113
+ /**
114
+ * Highlight color shown when the wave is on a char. Single RGB or
115
+ * per-char palette, same shape as `color`.
116
+ * @default [255, 255, 255] — pure white
117
+ */
118
+ readonly highlight?: RGB | Palette | undefined;
119
+ /**
120
+ * Wave direction. See {@link ShimmerDirection}.
121
+ * @default 'ltr'
122
+ */
123
+ readonly dir?: ShimmerDirection | undefined;
124
+ /**
125
+ * Steps the wave advances per frame. Lower values = slower wave.
126
+ * @default 1/3 (≈0.333) — three frames advance the wave by one char.
127
+ */
128
+ readonly speed?: number | undefined;
129
+ /**
130
+ * Off-screen padding in char units on each side. The wave starts and
131
+ * ends past the text by this much so it fades in/out cleanly.
132
+ * @default 2
133
+ */
134
+ readonly padding?: number | undefined;
135
+ /**
136
+ * Half-width of the wave in chars (used by `smoothKernel`). Higher =
137
+ * wider bright zone. Ignored when `kernel: 'block'`.
138
+ * @default 2.5
139
+ */
140
+ readonly width?: number | undefined;
141
+ /**
142
+ * Wave shape. `'block'` is a hard 3-char-wide highlight (claude-code
143
+ * behavior). `'smooth'` is a power-curve glow (the previous library's
144
+ * default).
145
+ * @default 'smooth'
146
+ */
147
+ readonly kernel?: 'block' | 'smooth' | undefined;
148
+ };
149
+ /**
150
+ * Default base color used by {@link configToSpec} when `color` is omitted.
151
+ * Socket purple — matches the spinner's default color.
152
+ */
153
+ export declare const DEFAULT_BASE_COLOR: RGB;
154
+ /**
155
+ * Default highlight color used by {@link configToSpec} when `highlight` is
156
+ * omitted. Pure white.
157
+ */
158
+ export declare const WHITE: RGB;
159
+ /**
160
+ * Linearly interpolate between two RGB colors. `t` is clamped to [0, 1].
161
+ *
162
+ * @param a color at `t=0`
163
+ * @param b color at `t=1`
164
+ * @param t blend factor; values outside [0, 1] are clamped
165
+ * @returns blended RGB with each channel rounded to integer
166
+ */
167
+ export declare function blendRgb(a: RGB, b: RGB, t: number): RGB;
168
+ /**
169
+ * Build a per-char palette function that cycles through a fixed palette:
170
+ * `(i) => palette[i % palette.length]`.
171
+ *
172
+ * @throws {Error} if `palette` is empty
173
+ */
174
+ export declare function gradient(palette: Palette): (i: number) => RGB;
175
+ /**
176
+ * Build a per-char palette function that returns the same color for every
177
+ * char index. Useful when shimmering text with a single base color.
178
+ */
179
+ export declare function solidColor(color: RGB): (i: number) => RGB;
180
+ /**
181
+ * Discrete on/off kernel — each char is either fully `highlightColor`
182
+ * (within `halfWidth` of the wave center) or fully `baseColor`. No blend.
183
+ *
184
+ * Matches claude-code's spinner behavior at `halfWidth=1` (a 3-char bright
185
+ * zone: the char at the wave center plus its left and right neighbors).
186
+ *
187
+ * @param halfWidth chars on each side of the wave center to highlight
188
+ * @default halfWidth=1
189
+ */
190
+ export declare function blockKernel(halfWidth?: number): Kernel;
191
+ /**
192
+ * Smooth blend kernel — char's color blends from `baseColor` toward
193
+ * `highlightColor` as it approaches the wave center. Falloff curve is
194
+ * `(1 - |d|/halfWidth)^falloff`, giving a soft glow with a wider radius
195
+ * than `blockKernel`.
196
+ *
197
+ * Matches socket-lib's previous default at `halfWidth=2.5, falloff=2.5`.
198
+ *
199
+ * @param halfWidth chars on each side affected by the wave
200
+ * @param falloff intensity exponent (higher = sharper peak)
201
+ * @default halfWidth=2.5, falloff=2.5
202
+ */
203
+ export declare function smoothKernel(halfWidth?: number, falloff?: number): Kernel;
204
+ /**
205
+ * Build a position function for bidirectional motion: the wave does one
206
+ * left-to-right pass, then one right-to-left pass, then loops.
207
+ *
208
+ * @param textLength number of chars in the target string
209
+ * @param padding off-screen chars on each side
210
+ * @default padding=2
211
+ */
212
+ export declare function bidirectionalSweep(textLength: number, padding?: number): (frame: number) => number;
213
+ /**
214
+ * Build a position function for left-to-right motion: the wave starts at
215
+ * `-padding` (off-screen left), advances by 1 per frame, exits at
216
+ * `textLength + padding`, then wraps.
217
+ *
218
+ * @param textLength number of chars in the target string
219
+ * @param padding off-screen chars on each side
220
+ * @default padding=2
221
+ */
222
+ export declare function ltrSweep(textLength: number, padding?: number): (frame: number) => number;
223
+ /**
224
+ * Build a position function that hides the wave forever. Returns
225
+ * `-Infinity` for every frame so the kernel always sees `signedDistance` >
226
+ * `halfWidth` and produces base colors. Used by `configToSpec` when
227
+ * `dir: 'none'`.
228
+ */
229
+ export declare function noSweep(): (frame: number) => number;
230
+ /**
231
+ * Build a position function that randomly picks LTR or RTL at each cycle
232
+ * boundary. The PRNG is configurable (defaults to `Math.random`) so callers
233
+ * can seed it for reproducible animations.
234
+ *
235
+ * @param textLength number of chars in the target string
236
+ * @param padding off-screen chars on each side
237
+ * @param random PRNG returning [0, 1); defaults to `Math.random`
238
+ * @default padding=2, random=Math.random
239
+ */
240
+ export declare function randomSweep(textLength: number, padding?: number, random?: () => number): (frame: number) => number;
241
+ /**
242
+ * Build a position function for right-to-left motion: the wave starts at
243
+ * the right edge, decreases by 1 per frame, exits at `-padding` left of
244
+ * char 0, then wraps.
245
+ *
246
+ * @param textLength number of chars in the target string
247
+ * @param padding off-screen chars on each side
248
+ * @default padding=2
249
+ */
250
+ export declare function rtlSweep(textLength: number, padding?: number): (frame: number) => number;
251
+ /**
252
+ * Translate a {@link ShimmerDirection} string to its position-generator
253
+ * function. Used by {@link configToSpec}; exported for callers that want
254
+ * to swap kernel or palette while keeping the standard sweep mapping.
255
+ */
256
+ export declare function directionToSweep(dir: ShimmerDirection, textLength: number, padding: number): (frame: number) => number;
257
+ /**
258
+ * Translate a flat {@link ShimmerConfig} into a {@link ShimmerSpec}.
259
+ * Applies defaults for omitted fields; resolves `color` and `highlight`
260
+ * (which may be a single RGB or a palette) into per-char palette
261
+ * functions.
262
+ *
263
+ * The spinner uses this internally; callers who only need the standard
264
+ * shape can call this directly. Advanced callers can construct a
265
+ * `ShimmerSpec` by hand to plug in custom kernels or position generators.
266
+ */
267
+ export declare function configToSpec(config: ShimmerConfig, textLength: number): ShimmerSpec;
268
+ /**
269
+ * Resolve a {@link ShimmerConfig.color}-shaped input into a per-char
270
+ * palette function. Accepts a single RGB tuple, an ordered palette, or
271
+ * `undefined` (in which case `defaultColor` is used).
272
+ *
273
+ * Used internally by {@link configToSpec}; exported so callers can build
274
+ * partial specs that share the same input-shape rules.
275
+ */
276
+ export declare function resolvePalette(source: RGB | Palette | undefined, defaultColor: RGB): (i: number) => RGB;
277
+ /**
278
+ * Compute per-character colors for a single frame. This is the engine.
279
+ *
280
+ * @param spec functional shimmer specification
281
+ * @param textLength number of chars to color
282
+ * @param frame caller-controlled frame counter (any number; the position
283
+ * generator handles wrapping)
284
+ * @returns one RGB tuple per char index, in order
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * const colors = frameColors(spec, 'Loading'.length, frameCounter)
289
+ * // colors[0] = the color of 'L' at this frame
290
+ * // colors[6] = the color of 'g' at this frame
291
+ * ```
292
+ */
293
+ export declare function frameColors(spec: ShimmerSpec, textLength: number, frame: number): RGB[];