@trawlme/cli 3.4.1 → 3.5.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.
@@ -3,29 +3,30 @@
3
3
  * art. Distinct from Clawd's 8-bit lane: Pinch is drawn with full 24-bit
4
4
  * (`\x1b[38;2;r;g;bm` / `\x1b[48;2;r;g;bm`) color blocks, not a fixed palette.
5
5
  *
6
- * The 9×6 cube-grid (#133 mini) is packed two grid rows into one terminal
7
- * row: the
8
- * upper row's color becomes the half-block's foreground, the lower row's
9
- * becomes its background, using the upper-half-block glyph '▀' (or '▄' when
10
- * only the lower half is filled). A 6-row grid therefore renders in 3
11
- * terminal rows, 9 columns wide. '.' cells are transparent — no color
12
- * escape is emitted for that half, so the terminal's own background shows
13
- * through.
6
+ * Each grid is packed two rows into one terminal row: the upper row's color
7
+ * becomes the half-block's foreground, the lower row's becomes its
8
+ * background, using the upper-half-block glyph '▀' (or '▄' when only the
9
+ * lower half is filled). '.' cells are transparent no color escape is
10
+ * emitted for that half, so the terminal's own background shows through.
14
11
  *
15
- * Grids + palette are mirrored from trawl_vue
16
- * `src/modules/trawl/assets/mascot/_src/pinch.model.mjs` (AVCOLORS +
17
- * AVATAR_GRIDS, rev r6f) — no cross-repo import (cli is a standalone npm
18
- * package). Claws are 1-wide 2-tall 'O' blocks at cols 0 / 8, on the SIDES
19
- * (raised for wave/thumbsup/celebrating/shocked), per the r6f shape.
12
+ * The grids are the founder-approved 2D front avatar (`AVATAR_GRIDS`, rev
13
+ * r6f) from trawl_vue `src/modules/trawl/assets/mascot/_src/pinch.model.mjs`,
14
+ * ported VERBATIM (no cross-repo import cli is a standalone npm package).
15
+ * Each is 14 cols × 8 rows (the source's 9th all-'.' pad row is dropped) →
16
+ * renders in 4 terminal rows, 14 columns wide. This is the mascot "de face":
17
+ * antennae on top, 2-wide white eyes + navy pupils, pink cheek blush, a
18
+ * U-smile (corners + a 2-wide dropped center), and the signature 2-WIDE
19
+ * orange claws on the body flanks (cols 0-1 / 12-13).
20
20
  *
21
- * State parity (#135): the CLI now carries all 9 canonical AVATAR_STATES
22
- * from the source model idle · working · celebrating · thumbsup · confused
23
- * · wave · heart · sleepy · shocked — with the SAME names (before #135 the
24
- * CLI shipped 4 states and called `working` "thinking", a name not in the
25
- * source). Each is a 9×6 mini redraw preserving that state's distinguishing
26
- * feature.
21
+ * History: #133 shrank this to a 9×6 mini (1-wide claws, a single-pixel
22
+ * mouth) #141 reverted to this faithful 14×9 founder art after it read as
23
+ * "trop loin du 3D".
27
24
  *
28
- * See comes-io/trawl_cli#94, comes-io/trawl_cli#122, comes-io/trawl_cli#135.
25
+ * State parity (#135): the CLI carries all 9 canonical AVATAR_STATES with the
26
+ * source's own names — idle · working · celebrating · thumbsup · confused ·
27
+ * wave · heart · sleepy · shocked.
28
+ *
29
+ * See comes-io/trawl_cli#94, #122, #135, #141.
29
30
  */
30
31
  export type PinchState = 'idle' | 'working' | 'celebrating' | 'thumbsup' | 'confused' | 'wave' | 'heart' | 'sleepy' | 'shocked';
31
32
  /** All 9 canonical states, in the source model's AVATAR_STATES order. */
@@ -42,20 +43,15 @@ export declare function renderPinch(state: PinchState, frame?: number): string;
42
43
  /**
43
44
  * #131 — the ART lines only (no caption), optionally COMPACT: trailing and
44
45
  * leading fully-transparent grid rows are dropped so Pinch takes fewer
45
- * terminal lines (some grids carry an all-'.' padding row). Used by the
46
- * animation loop, where a caption + full height would be too heavy for a
47
- * frame redrawn every ~380ms. `working` is rendered at frame 0 (blip on).
46
+ * terminal lines (confused/sleepy carry an all-'.' leading row). `frame` is
47
+ * passed through to `gridForState` only `working` reacts to it (the cyan
48
+ * antenna blip toggles), so the loop can pulse the tips while the body stays
49
+ * still.
48
50
  */
49
51
  export declare function renderPinchArt(state: PinchState, opts?: {
50
52
  compact?: boolean;
53
+ frame?: number;
51
54
  }): string;
52
- /**
53
- * #131 — frame sequence for the "working" animation shown during long waits
54
- * (the `create` wizard, `--watch`). The claws pump up (working → wave →
55
- * celebrating) and back down, reading as Pinch busily working. No new art —
56
- * an order over the canonical state grids.
57
- */
58
- export declare const WORKING_FRAMES: readonly PinchState[];
59
55
  /**
60
56
  * True when it's safe to print Pinch art: a real color-capable interactive
61
57
  * terminal. False under NO_COLOR (https://no-color.org — presence, not
package/dist/lib/pinch.js CHANGED
@@ -3,29 +3,30 @@
3
3
  * art. Distinct from Clawd's 8-bit lane: Pinch is drawn with full 24-bit
4
4
  * (`\x1b[38;2;r;g;bm` / `\x1b[48;2;r;g;bm`) color blocks, not a fixed palette.
5
5
  *
6
- * The 9×6 cube-grid (#133 mini) is packed two grid rows into one terminal
7
- * row: the
8
- * upper row's color becomes the half-block's foreground, the lower row's
9
- * becomes its background, using the upper-half-block glyph '▀' (or '▄' when
10
- * only the lower half is filled). A 6-row grid therefore renders in 3
11
- * terminal rows, 9 columns wide. '.' cells are transparent — no color
12
- * escape is emitted for that half, so the terminal's own background shows
13
- * through.
6
+ * Each grid is packed two rows into one terminal row: the upper row's color
7
+ * becomes the half-block's foreground, the lower row's becomes its
8
+ * background, using the upper-half-block glyph '▀' (or '▄' when only the
9
+ * lower half is filled). '.' cells are transparent no color escape is
10
+ * emitted for that half, so the terminal's own background shows through.
14
11
  *
15
- * Grids + palette are mirrored from trawl_vue
16
- * `src/modules/trawl/assets/mascot/_src/pinch.model.mjs` (AVCOLORS +
17
- * AVATAR_GRIDS, rev r6f) — no cross-repo import (cli is a standalone npm
18
- * package). Claws are 1-wide 2-tall 'O' blocks at cols 0 / 8, on the SIDES
19
- * (raised for wave/thumbsup/celebrating/shocked), per the r6f shape.
12
+ * The grids are the founder-approved 2D front avatar (`AVATAR_GRIDS`, rev
13
+ * r6f) from trawl_vue `src/modules/trawl/assets/mascot/_src/pinch.model.mjs`,
14
+ * ported VERBATIM (no cross-repo import cli is a standalone npm package).
15
+ * Each is 14 cols × 8 rows (the source's 9th all-'.' pad row is dropped) →
16
+ * renders in 4 terminal rows, 14 columns wide. This is the mascot "de face":
17
+ * antennae on top, 2-wide white eyes + navy pupils, pink cheek blush, a
18
+ * U-smile (corners + a 2-wide dropped center), and the signature 2-WIDE
19
+ * orange claws on the body flanks (cols 0-1 / 12-13).
20
20
  *
21
- * State parity (#135): the CLI now carries all 9 canonical AVATAR_STATES
22
- * from the source model idle · working · celebrating · thumbsup · confused
23
- * · wave · heart · sleepy · shocked — with the SAME names (before #135 the
24
- * CLI shipped 4 states and called `working` "thinking", a name not in the
25
- * source). Each is a 9×6 mini redraw preserving that state's distinguishing
26
- * feature.
21
+ * History: #133 shrank this to a 9×6 mini (1-wide claws, a single-pixel
22
+ * mouth) #141 reverted to this faithful 14×9 founder art after it read as
23
+ * "trop loin du 3D".
27
24
  *
28
- * See comes-io/trawl_cli#94, comes-io/trawl_cli#122, comes-io/trawl_cli#135.
25
+ * State parity (#135): the CLI carries all 9 canonical AVATAR_STATES with the
26
+ * source's own names — idle · working · celebrating · thumbsup · confused ·
27
+ * wave · heart · sleepy · shocked.
28
+ *
29
+ * See comes-io/trawl_cli#94, #122, #135, #141.
29
30
  */
30
31
  /** Grid-char → RGB, ported from AVCOLORS (pinch.model.mjs, rev r6f). 'C'
31
32
  * (cyan) is the `working` thinking-blip — not present in any static grid,
@@ -52,107 +53,125 @@ export const PINCH_STATES = [
52
53
  'shocked',
53
54
  ];
54
55
  /**
55
- * Explicit per-state 9×6 grids (#133 mini shape, #135 full state parity).
56
- * The 14×9 grids were ported from trawl_vue's AVATAR_GRIDS (pinch.model.mjs,
57
- * rev r6f); these mini redraws preserve each state's feature at a smaller
58
- * pixel count. Grid layout (cols 0-8, body/shell cols 1-7):
59
- * row 0 antennae (O at cols 2,6 spread to 1,7 when drooped)
60
- * row 1 head top (+ claw at col 0/8 when RAISED)
61
- * row 2 eyes (+ claw at col 0/8 when RAISED)
62
- * row 3 head mid
63
- * row 4 mouth corners + blush (+ claw at col 0/8 when RESTING)
64
- * row 5 head bottom + mouth center (+ claw at col 0/8 when RESTING)
65
- * Claws are the 1-wide 2-tall O blocks at cols 0/8. Eyes: left = W+K at
66
- * cols 2-3, right = K+W at cols 5-6 (pupils inward). The smile is a U (like
67
- * the source 3D / AVGRID): the mouth CORNERS sit on row 4 and the CENTER
68
- * dips to row 5 — never a flat single-row bar (#137).
56
+ * The founder 2D front avatar grids (`AVATAR_GRIDS`, pinch.model.mjs rev
57
+ * r6f), ported VERBATIM rows 0-7 of each 9-row grid (the trailing all-'.'
58
+ * pad row 8 is dropped; it only exists to square the SVG canvas). 14 cols,
59
+ * 8 rows 4 terminal lines. Layout:
60
+ * rows 0-1 antennae (2 orange, drooped/spread for confused & sleepy)
61
+ * row 2 head top (+ claw at cols 0-1/12-13 when RAISED)
62
+ * rows 3-4 eyes: 2-wide W whites (row 3) + K pupils (row 4)
63
+ * row 5 head mid
64
+ * rows 6-7 mouth + blush + the 2-WIDE claws on the flanks
65
+ * The claws are 2×2 O blocks OUTSIDE the body silhouette (cols 0-1 / 12-13),
66
+ * raised to rows 3-4 for celebrating / shocked (and the right claw for
67
+ * wave / thumbsup). The smile is a U: corners K on row 6, a 2-wide center
68
+ * KK on row 7.
69
69
  */
70
70
  const GRIDS = {
71
- // calm resting face, both claws down, normal smile.
72
71
  idle: [
73
- '..O...O..',
74
- '.BBBBBBB.',
75
- '.BWKBKWB.',
76
- '.BBBBBBB.',
77
- 'OBPKBKPBO',
78
- 'OBBBKBBBO',
72
+ '....O....O....',
73
+ '....O....O....',
74
+ '..BBBBBBBBBB..',
75
+ '..BWWBBBBWWB..',
76
+ '..BWKBBBBKWB..',
77
+ '..BBBBBBBBBB..',
78
+ 'OOBBPKBBKPBBOO',
79
+ 'OOBBBBKKBBBBOO',
79
80
  ],
80
81
  // idle pose + the cyan thinking-blip on the antenna tips (frame-toggled in
81
82
  // `gridForState`) — the only animated static state.
82
83
  working: [
83
- '..O...O..',
84
- '.BBBBBBB.',
85
- '.BWKBKWB.',
86
- '.BBBBBBB.',
87
- 'OBPKBKPBO',
88
- 'OBBBKBBBO',
84
+ '....O....O....',
85
+ '....O....O....',
86
+ '..BBBBBBBBBB..',
87
+ '..BWWBBBBWWB..',
88
+ '..BWKBBBBKWB..',
89
+ '..BBBBBBBBBB..',
90
+ 'OOBBPKBBKPBBOO',
91
+ 'OOBBBBKKBBBBOO',
89
92
  ],
90
- // both claws raised (rows 1-2) + a big open mouth.
93
+ // both claws raised to rows 3-4 + a big open mouth (rows 6-7).
91
94
  celebrating: [
92
- '..O...O..',
93
- 'OBBBBBBBO',
94
- 'OBWKBKWBO',
95
- '.BBBBBBB.',
96
- '.BKBBBKB.',
97
- '.BBKKKBB.',
95
+ '....O....O....',
96
+ '....O....O....',
97
+ '..BBBBBBBBBB..',
98
+ 'OOBWWBBBBWWBOO',
99
+ 'OOBWKBBBBKWBOO',
100
+ '..BBBBBBBBBB..',
101
+ '..BBPKKKKPBB..',
102
+ '..BBBKKKKBBB..',
98
103
  ],
99
- // right claw raised (rows 1-2) + a thumb pixel poking up above it (row 0,
100
- // col 8); left claw resting.
104
+ // right claw raised (rows 3-4) + a thumb pixel poking up (row 2, col 12);
105
+ // left claw resting on the flank (rows 6-7).
101
106
  thumbsup: [
102
- '..O...O.O',
103
- '.BBBBBBBO',
104
- '.BWKBKWBO',
105
- '.BBBBBBB.',
106
- 'OBPKBKPB.',
107
- 'OBBBKBBB.',
107
+ '....O....O....',
108
+ '....O....O....',
109
+ '..BBBBBBBBBBO.',
110
+ '..BWWBBBBWWBOO',
111
+ '..BWKBBBBKWBOO',
112
+ '..BBBBBBBBBB..',
113
+ 'OOBBPKBBKPBB..',
114
+ 'OOBBBBKKBBBB..',
108
115
  ],
109
- // antennae drooped + spread, flat mouth (no K), claws resting. A '?' is
110
- // appended beside the eye line by `renderPinch`.
116
+ // antennae drooped + spread (row 1, cols 3 & 10), flat mouth (blush only, no
117
+ // smile K on row 6), claws resting. A '?' is appended by `renderPinch`.
111
118
  confused: [
112
- '.O.....O.',
113
- '.BBBBBBB.',
114
- '.BWKBKWB.',
115
- '.BBBBBBB.',
116
- 'OBPBBBPBO',
117
- 'OBBBBBBBO',
119
+ '..............',
120
+ '...O......O...',
121
+ '..BBBBBBBBBB..',
122
+ '..BWWBBBBWWB..',
123
+ '..BWKBBBBKWB..',
124
+ '..BBBBBBBBBB..',
125
+ 'OOBBPBBBBPBBOO',
126
+ 'OOBBBBKKBBBBOO',
118
127
  ],
119
- // right claw raised (rows 1-2), left claw resting; base face.
128
+ // right claw raised (rows 3-4), left claw resting; base face.
120
129
  wave: [
121
- '..O...O..',
122
- '.BBBBBBBO',
123
- '.BWKBKWBO',
124
- '.BBBBBBB.',
125
- 'OBPKBKPB.',
126
- 'OBBBKBBB.',
130
+ '....O....O....',
131
+ '....O....O....',
132
+ '..BBBBBBBBBB..',
133
+ '..BWWBBBBWWBOO',
134
+ '..BWKBBBBKWBOO',
135
+ '..BBBBBBBBBB..',
136
+ 'OOBBPKBBKPBB..',
137
+ 'OOBBBBKKBBBB..',
127
138
  ],
128
- // pink heart-eyes (P replaces the W+K pupils), claws resting, normal smile.
139
+ // pink heart-eyes (P fills both eye blocks, rows 3-4), claws resting, normal
140
+ // smile.
129
141
  heart: [
130
- '..O...O..',
131
- '.BBBBBBB.',
132
- '.BPPBPPB.',
133
- '.BBBBBBB.',
134
- 'OBPKBKPBO',
135
- 'OBBBKBBBO',
142
+ '....O....O....',
143
+ '....O....O....',
144
+ '..BBBBBBBBBB..',
145
+ '..BPPBBBBPPB..',
146
+ '..BPPBBBBPPB..',
147
+ '..BBBBBBBBBB..',
148
+ 'OOBBPKBBKPBBOO',
149
+ 'OOBBBBKKBBBBOO',
136
150
  ],
137
- // closed eyes (flat K line, no white), antennae drooped + spread, flat
138
- // mouth, claws resting — like confused but eyes shut and no '?'.
151
+ // closed eyes (flat K line on row 4, no white), antennae drooped + spread,
152
+ // flat mouth, claws resting — like confused but eyes shut and no '?'.
139
153
  sleepy: [
140
- '.O.....O.',
141
- '.BBBBBBB.',
142
- '.BKKBKKB.',
143
- '.BBBBBBB.',
144
- 'OBPBBBPBO',
145
- 'OBBBBBBBO',
154
+ '..............',
155
+ '...O......O...',
156
+ '..BBBBBBBBBB..',
157
+ '..BWWBBBBWWB..',
158
+ '..BKKBBBBKKB..',
159
+ '..BBBBBBBBBB..',
160
+ 'OOBBPBBBBPBBOO',
161
+ 'OOBBBBKKBBBBOO',
146
162
  ],
147
- // both claws raised (rows 1-2) + a small round mouth (single K, row 4)
148
- // like celebrating's raise but a startled dot mouth, not the wide smile.
163
+ // pupils up a row (row 3 carries K, row 4 all white), both claws raised
164
+ // (rows 3-4), a small round mouth (row 6 only) — startled, not the wide
165
+ // celebrating grin.
149
166
  shocked: [
150
- '..O...O..',
151
- 'OBBBBBBBO',
152
- 'OBWKBKWBO',
153
- '.BBBBBBB.',
154
- '.BBBKBBB.',
155
- '.BBBBBBB.',
167
+ '....O....O....',
168
+ '....O....O....',
169
+ '..BBBBBBBBBB..',
170
+ 'OOBWKBBBBKWBOO',
171
+ 'OOBWWBBBBWWBOO',
172
+ '..BBBBBBBBBB..',
173
+ '..BBPBKKBPBB..',
174
+ '..BBBBBBBBBB..',
156
175
  ],
157
176
  };
158
177
  const CAPTIONS = {
@@ -166,8 +185,8 @@ const CAPTIONS = {
166
185
  sleepy: 'Pinch is sleepy…',
167
186
  shocked: 'Pinch is shocked!',
168
187
  };
169
- /** Antenna-tip cells (row 0) for the `working` cyan blip: cols 2 & 6. */
170
- const ANTENNA_TIP_COLS = [2, 6];
188
+ /** Antenna-tip cells (grid row 0) for the `working` cyan blip: cols 4 & 9. */
189
+ const ANTENNA_TIP_COLS = [4, 9];
171
190
  /** Replace the chars at `indices` in `row` with `ch` — never mutates `row`. */
172
191
  function setCells(row, indices, ch) {
173
192
  const chars = row.split('');
@@ -212,7 +231,7 @@ function renderCell(upper, lower) {
212
231
  return `${fgCode(upperColor)}${bgCode(lowerColor)}▀${RESET}`;
213
232
  }
214
233
  /** Pack a grid into terminal lines, 2 grid rows per line (upper=fg, lower=bg).
215
- * The #133 mini grid is 6 rows → 3 lines. */
234
+ * The 14×8 founder grid is 8 rows → 4 lines. */
216
235
  function renderGrid(rows) {
217
236
  const lines = [];
218
237
  for (let i = 0; i < rows.length; i += 2) {
@@ -238,8 +257,8 @@ export function renderPinch(state, frame = 0) {
238
257
  const grid = gridForState(state, frame);
239
258
  const lines = renderGrid(grid);
240
259
  if (state === 'confused') {
241
- // "beside the art" — a bold '?' to the right of the eye row. In the #133
242
- // mini grid the eyes are grid rows 2-3, which pack into terminal line 1.
260
+ // "beside the art" — a bold '?' to the right of the eye row. The eyes are
261
+ // grid rows 2-3 (head-top + eye-whites), which pack into terminal line 1.
243
262
  lines[1] = `${lines[1]} \x1b[1m?${RESET}`;
244
263
  }
245
264
  return [...lines, CAPTIONS[state]].join('\n');
@@ -247,12 +266,13 @@ export function renderPinch(state, frame = 0) {
247
266
  /**
248
267
  * #131 — the ART lines only (no caption), optionally COMPACT: trailing and
249
268
  * leading fully-transparent grid rows are dropped so Pinch takes fewer
250
- * terminal lines (some grids carry an all-'.' padding row). Used by the
251
- * animation loop, where a caption + full height would be too heavy for a
252
- * frame redrawn every ~380ms. `working` is rendered at frame 0 (blip on).
269
+ * terminal lines (confused/sleepy carry an all-'.' leading row). `frame` is
270
+ * passed through to `gridForState` only `working` reacts to it (the cyan
271
+ * antenna blip toggles), so the loop can pulse the tips while the body stays
272
+ * still.
253
273
  */
254
274
  export function renderPinchArt(state, opts = {}) {
255
- let grid = gridForState(state, 0);
275
+ let grid = gridForState(state, opts.frame ?? 0);
256
276
  if (opts.compact) {
257
277
  const blank = (row) => [...row].every((c) => c === TRANSPARENT);
258
278
  let start = 0;
@@ -268,13 +288,6 @@ export function renderPinchArt(state, opts = {}) {
268
288
  lines[1] = `${lines[1]} \x1b[1m?${RESET}`;
269
289
  return lines.join('\n');
270
290
  }
271
- /**
272
- * #131 — frame sequence for the "working" animation shown during long waits
273
- * (the `create` wizard, `--watch`). The claws pump up (working → wave →
274
- * celebrating) and back down, reading as Pinch busily working. No new art —
275
- * an order over the canonical state grids.
276
- */
277
- export const WORKING_FRAMES = ['working', 'wave', 'celebrating', 'wave'];
278
291
  /**
279
292
  * True when it's safe to print Pinch art: a real color-capable interactive
280
293
  * terminal. False under NO_COLOR (https://no-color.org — presence, not
@@ -4,9 +4,12 @@ export interface PinchAnimation {
4
4
  stop(): void;
5
5
  }
6
6
  /**
7
- * #131 — animate Pinch (a claw-wiggle over the r6f grids) IN PLACE on STDERR
8
- * while a long operation runs (the `create` wizard, `--watch`). The frame is
9
- * redrawn every {@link FRAME_MS} via ANSI cursor moves; `stop()` clears it.
7
+ * #131 / #139 show Pinch IN PLACE on STDERR while a long operation runs (the
8
+ * `create` wizard, `--watch`). Pinch stays a STILL `working` sprite; the ONLY
9
+ * animation is the cyan antenna-tip blip pulsing on/off every {@link FRAME_MS}
10
+ * (frame 0 = cyan, frame 1 = orange). The body — mouth, claws, eyes — never
11
+ * moves (the old loop cycled whole poses, which flickered "in every
12
+ * direction"). Redrawn via ANSI cursor moves; `stop()` clears the block.
10
13
  *
11
14
  * Contract: the CALLER must have already checked `pinchEnabled()` (TTY /
12
15
  * !NO_COLOR) and that the command is NOT `--json` — this writes only to
@@ -1,11 +1,16 @@
1
1
  import chalk from 'chalk';
2
- import { renderPinchArt, WORKING_FRAMES } from './pinch.js';
3
- /** Frame cadence — slow enough to read as a wave, fast enough to feel alive. */
4
- const FRAME_MS = 380;
2
+ import { renderPinchArt } from './pinch.js';
3
+ /** Frame cadence — a calm, ~2/second pulse. The only thing that moves is the
4
+ * cyan antenna blip, so this is intentionally slow: a fast rate on a 2-pixel
5
+ * color change reads as a nervous flicker. */
6
+ const FRAME_MS = 600;
5
7
  /**
6
- * #131 — animate Pinch (a claw-wiggle over the r6f grids) IN PLACE on STDERR
7
- * while a long operation runs (the `create` wizard, `--watch`). The frame is
8
- * redrawn every {@link FRAME_MS} via ANSI cursor moves; `stop()` clears it.
8
+ * #131 / #139 show Pinch IN PLACE on STDERR while a long operation runs (the
9
+ * `create` wizard, `--watch`). Pinch stays a STILL `working` sprite; the ONLY
10
+ * animation is the cyan antenna-tip blip pulsing on/off every {@link FRAME_MS}
11
+ * (frame 0 = cyan, frame 1 = orange). The body — mouth, claws, eyes — never
12
+ * moves (the old loop cycled whole poses, which flickered "in every
13
+ * direction"). Redrawn via ANSI cursor moves; `stop()` clears the block.
9
14
  *
10
15
  * Contract: the CALLER must have already checked `pinchEnabled()` (TTY /
11
16
  * !NO_COLOR) and that the command is NOT `--json` — this writes only to
@@ -14,7 +19,12 @@ const FRAME_MS = 380;
14
19
  * own.
15
20
  */
16
21
  export function startPinchAnimation(statusText) {
17
- const frames = WORKING_FRAMES.map((s) => renderPinchArt(s, { compact: true }));
22
+ // Two frames of the SAME `working` sprite identical geometry, the antenna
23
+ // tips just toggle cyan↔orange. Nothing else changes between frames.
24
+ const frames = [
25
+ renderPinchArt('working', { compact: true, frame: 0 }), // cyan tips
26
+ renderPinchArt('working', { compact: true, frame: 1 }), // orange tips
27
+ ];
18
28
  const artHeight = frames[0].split('\n').length;
19
29
  const totalHeight = artHeight + 1; // + the status line below the art
20
30
  const out = process.stderr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trawlme/cli",
3
- "version": "3.4.1",
3
+ "version": "3.5.0",
4
4
  "description": "Trawl CLI — manage scraps from the terminal",
5
5
  "type": "module",
6
6
  "bin": {