@trawlme/cli 3.3.0 → 3.4.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.
@@ -15,36 +15,45 @@
15
15
  * Grids + palette are mirrored from trawl_vue
16
16
  * `src/modules/trawl/assets/mascot/_src/pinch.model.mjs` (AVCOLORS +
17
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 (raised
19
- * for wave/celebrating), per the r6f shape (#133 shrank the sprite).
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.
20
20
  *
21
- * See comes-io/trawl_cli#94, comes-io/trawl_cli#122.
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.
27
+ *
28
+ * See comes-io/trawl_cli#94, comes-io/trawl_cli#122, comes-io/trawl_cli#135.
22
29
  */
23
- export type PinchState = 'wave' | 'thinking' | 'celebrating' | 'confused';
30
+ export type PinchState = 'idle' | 'working' | 'celebrating' | 'thumbsup' | 'confused' | 'wave' | 'heart' | 'sleepy' | 'shocked';
31
+ /** All 9 canonical states, in the source model's AVATAR_STATES order. */
32
+ export declare const PINCH_STATES: readonly PinchState[];
24
33
  /**
25
34
  * Render Pinch as 24-bit ANSI half-block art for the given state, plus a
26
35
  * one-line caption. Pure — never touches process.env/stdout; callers must
27
36
  * gate on `pinchEnabled()` before printing the result.
28
37
  *
29
- * `frame` is accepted for signature stability but currently unused every
30
- * state's grid is static (see `gridForState`).
38
+ * `frame` only affects `working` (the cyan antenna-tip blip alternates every
39
+ * frame); every other state's grid is static.
31
40
  */
32
41
  export declare function renderPinch(state: PinchState, frame?: number): string;
33
42
  /**
34
43
  * #131 — the ART lines only (no caption), optionally COMPACT: trailing and
35
44
  * leading fully-transparent grid rows are dropped so Pinch takes fewer
36
- * terminal lines (the r6f grids carry an all-'.' bottom row + blank-ish
37
- * antenna padding). Used by the animation loop, where a caption + full
38
- * height would be too heavy for a frame redrawn every ~380ms.
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).
39
48
  */
40
49
  export declare function renderPinchArt(state: PinchState, opts?: {
41
50
  compact?: boolean;
42
51
  }): string;
43
52
  /**
44
53
  * #131 — frame sequence for the "working" animation shown during long waits
45
- * (the `create` wizard, `--watch`). Reuses the existing r6f state grids: the
46
- * claws pump up (wave → celebrating) and back down, reading as Pinch busily
47
- * waving while it works. No new art — just an order over the grids we have.
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.
48
57
  */
49
58
  export declare const WORKING_FRAMES: readonly PinchState[];
50
59
  /**
package/dist/lib/pinch.js CHANGED
@@ -15,43 +15,69 @@
15
15
  * Grids + palette are mirrored from trawl_vue
16
16
  * `src/modules/trawl/assets/mascot/_src/pinch.model.mjs` (AVCOLORS +
17
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 (raised
19
- * for wave/celebrating), per the r6f shape (#133 shrank the sprite).
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.
20
20
  *
21
- * See comes-io/trawl_cli#94, comes-io/trawl_cli#122.
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.
27
+ *
28
+ * See comes-io/trawl_cli#94, comes-io/trawl_cli#122, comes-io/trawl_cli#135.
22
29
  */
23
- /** Grid-char → RGB, ported from AVCOLORS (pinch.model.mjs, rev r6f). */
30
+ /** Grid-char → RGB, ported from AVCOLORS (pinch.model.mjs, rev r6f). 'C'
31
+ * (cyan) is the `working` thinking-blip — not present in any static grid,
32
+ * injected per-frame on the antenna tips. */
24
33
  const PALETTE = {
25
34
  B: [0x29, 0x79, 0xff], // blue — shell
26
35
  O: [0xfb, 0x92, 0x3c], // orange — antennae / claws
27
36
  W: [0xff, 0xff, 0xff], // white — eye whites
28
37
  K: [0x12, 0x30, 0x33], // navy — pupils / mouth / blush-adjacent mouth corner
29
- P: [0xf4, 0x72, 0xb6], // pink — blush
38
+ P: [0xf4, 0x72, 0xb6], // pink — blush / heart-eyes
39
+ C: [0x06, 0xb6, 0xd4], // cyan — `working` thinking-blip on the antenna tips
30
40
  };
31
41
  const TRANSPARENT = '.';
42
+ /** All 9 canonical states, in the source model's AVATAR_STATES order. */
43
+ export const PINCH_STATES = [
44
+ 'idle',
45
+ 'working',
46
+ 'celebrating',
47
+ 'thumbsup',
48
+ 'confused',
49
+ 'wave',
50
+ 'heart',
51
+ 'sleepy',
52
+ 'shocked',
53
+ ];
32
54
  /**
33
- * Explicit per-state 9×6 grids (#133 mini). The 14×9 grids were ported
34
- * verbatim from trawl_vue's AVATAR_GRIDS (pinch.model.mjs, rev r6f); this
35
- * mini redraw preserves the same features + shape at a smaller pixel count.
36
- * CLI state pose: wave, thinking (idle/working), celebrating, confused.
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 + blush (+ claw at col 0/8 when RESTING)
64
+ * row 5 head bottom (+ 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).
37
67
  */
38
68
  const GRIDS = {
39
- // #133 MINI redraw: 9 cols × 6 rows (was the 14×9 r6f port), so Pinch
40
- // renders in 3 terminal lines instead of 4-5. Half-block is the ANSI floor
41
- // (2px/line) so "smaller" means fewer pixels, not scaling — this keeps all
42
- // r6f features (antennae O, eyes W+K pupils, blush P, mouth K, and the
43
- // signature claws as 1-wide 2-tall O blocks on the SIDES at cols 0/8,
44
- // raised for wave/celebrating). Body/shell spans cols 1-7.
45
- wave: [
69
+ // calm resting face, both claws down, normal smile.
70
+ idle: [
46
71
  '..O...O..',
47
- '.BBBBBBBO', // right claw raised (cols 8, rows 1-2)
48
- '.BWKBKWBO',
49
72
  '.BBBBBBB.',
50
- 'OBPKKKPB.', // left claw resting (col 0, rows 4-5) + blush + mouth
51
- 'OBBBBBBB.',
73
+ '.BWKBKWB.',
74
+ '.BBBBBBB.',
75
+ 'OBPKKKPBO',
76
+ 'OBBBBBBBO',
52
77
  ],
53
- // 'thinking' = the idle/working pose: both claws resting low (rows 4-5).
54
- thinking: [
78
+ // idle pose + the cyan thinking-blip on the antenna tips (frame-toggled in
79
+ // `gridForState`) — the only animated static state.
80
+ working: [
55
81
  '..O...O..',
56
82
  '.BBBBBBB.',
57
83
  '.BWKBKWB.',
@@ -68,7 +94,18 @@ const GRIDS = {
68
94
  '.BKKKKKB.',
69
95
  '.BBBBBBB.',
70
96
  ],
71
- // antennae drooped + spread, flat mouth (no K), claws resting.
97
+ // right claw raised (rows 1-2) + a thumb pixel poking up above it (row 0,
98
+ // col 8); left claw resting.
99
+ thumbsup: [
100
+ '..O...O.O',
101
+ '.BBBBBBBO',
102
+ '.BWKBKWBO',
103
+ '.BBBBBBB.',
104
+ 'OBPKKKPB.',
105
+ 'OBBBBBBB.',
106
+ ],
107
+ // antennae drooped + spread, flat mouth (no K), claws resting. A '?' is
108
+ // appended beside the eye line by `renderPinch`.
72
109
  confused: [
73
110
  '.O.....O.',
74
111
  '.BBBBBBB.',
@@ -77,16 +114,75 @@ const GRIDS = {
77
114
  'OBPBBBPBO',
78
115
  'OBBBBBBBO',
79
116
  ],
117
+ // right claw raised (rows 1-2), left claw resting; base face.
118
+ wave: [
119
+ '..O...O..',
120
+ '.BBBBBBBO',
121
+ '.BWKBKWBO',
122
+ '.BBBBBBB.',
123
+ 'OBPKKKPB.',
124
+ 'OBBBBBBB.',
125
+ ],
126
+ // pink heart-eyes (P replaces the W+K pupils), claws resting, normal smile.
127
+ heart: [
128
+ '..O...O..',
129
+ '.BBBBBBB.',
130
+ '.BPPBPPB.',
131
+ '.BBBBBBB.',
132
+ 'OBPKKKPBO',
133
+ 'OBBBBBBBO',
134
+ ],
135
+ // closed eyes (flat K line, no white), antennae drooped + spread, flat
136
+ // mouth, claws resting — like confused but eyes shut and no '?'.
137
+ sleepy: [
138
+ '.O.....O.',
139
+ '.BBBBBBB.',
140
+ '.BKKBKKB.',
141
+ '.BBBBBBB.',
142
+ 'OBPBBBPBO',
143
+ 'OBBBBBBBO',
144
+ ],
145
+ // both claws raised (rows 1-2) + a small round mouth (single K, row 4) —
146
+ // like celebrating's raise but a startled dot mouth, not the wide smile.
147
+ shocked: [
148
+ '..O...O..',
149
+ 'OBBBBBBBO',
150
+ 'OBWKBKWBO',
151
+ '.BBBBBBB.',
152
+ '.BBBKBBB.',
153
+ '.BBBBBBB.',
154
+ ],
80
155
  };
81
156
  const CAPTIONS = {
82
- wave: 'Pinch says hi.',
83
- thinking: 'Pinch is thinking…',
157
+ idle: 'Pinch is here.',
158
+ working: 'Pinch is working…',
84
159
  celebrating: 'Pinch is celebrating!',
160
+ thumbsup: 'Pinch approves!',
85
161
  confused: 'Pinch looks confused.',
162
+ wave: 'Pinch says hi.',
163
+ heart: 'Pinch loves it.',
164
+ sleepy: 'Pinch is sleepy…',
165
+ shocked: 'Pinch is shocked!',
86
166
  };
87
- /** Look up the grid for `state`. `frame` is accepted (signature stability
88
- * for `renderPinch`) but unused — every current state's grid is static. */
89
- function gridForState(state, _frame) {
167
+ /** Antenna-tip cells (row 0) for the `working` cyan blip: cols 2 & 6. */
168
+ const ANTENNA_TIP_COLS = [2, 6];
169
+ /** Replace the chars at `indices` in `row` with `ch` — never mutates `row`. */
170
+ function setCells(row, indices, ch) {
171
+ const chars = row.split('');
172
+ for (const i of indices)
173
+ chars[i] = ch;
174
+ return chars.join('');
175
+ }
176
+ /** Look up the grid for `state`. `frame` only affects `working`: on even
177
+ * frames its antenna tips blip cyan (the thinking indicator), on odd frames
178
+ * they stay orange — a 2-frame pulse with no layout shift. Every other
179
+ * state's grid is static and ignores `frame`. */
180
+ function gridForState(state, frame) {
181
+ if (state === 'working' && frame % 2 === 0) {
182
+ const rows = [...GRIDS.working];
183
+ rows[0] = setCells(rows[0], ANTENNA_TIP_COLS, 'C');
184
+ return rows;
185
+ }
90
186
  return GRIDS[state];
91
187
  }
92
188
  const RESET = '\x1b[0m';
@@ -133,8 +229,8 @@ function renderGrid(rows) {
133
229
  * one-line caption. Pure — never touches process.env/stdout; callers must
134
230
  * gate on `pinchEnabled()` before printing the result.
135
231
  *
136
- * `frame` is accepted for signature stability but currently unused every
137
- * state's grid is static (see `gridForState`).
232
+ * `frame` only affects `working` (the cyan antenna-tip blip alternates every
233
+ * frame); every other state's grid is static.
138
234
  */
139
235
  export function renderPinch(state, frame = 0) {
140
236
  const grid = gridForState(state, frame);
@@ -149,9 +245,9 @@ export function renderPinch(state, frame = 0) {
149
245
  /**
150
246
  * #131 — the ART lines only (no caption), optionally COMPACT: trailing and
151
247
  * leading fully-transparent grid rows are dropped so Pinch takes fewer
152
- * terminal lines (the r6f grids carry an all-'.' bottom row + blank-ish
153
- * antenna padding). Used by the animation loop, where a caption + full
154
- * height would be too heavy for a frame redrawn every ~380ms.
248
+ * terminal lines (some grids carry an all-'.' padding row). Used by the
249
+ * animation loop, where a caption + full height would be too heavy for a
250
+ * frame redrawn every ~380ms. `working` is rendered at frame 0 (blip on).
155
251
  */
156
252
  export function renderPinchArt(state, opts = {}) {
157
253
  let grid = gridForState(state, 0);
@@ -172,11 +268,11 @@ export function renderPinchArt(state, opts = {}) {
172
268
  }
173
269
  /**
174
270
  * #131 — frame sequence for the "working" animation shown during long waits
175
- * (the `create` wizard, `--watch`). Reuses the existing r6f state grids: the
176
- * claws pump up (wave → celebrating) and back down, reading as Pinch busily
177
- * waving while it works. No new art — just an order over the grids we have.
271
+ * (the `create` wizard, `--watch`). The claws pump up (working wave →
272
+ * celebrating) and back down, reading as Pinch busily working. No new art —
273
+ * an order over the canonical state grids.
178
274
  */
179
- export const WORKING_FRAMES = ['thinking', 'wave', 'celebrating', 'wave'];
275
+ export const WORKING_FRAMES = ['working', 'wave', 'celebrating', 'wave'];
180
276
  /**
181
277
  * True when it's safe to print Pinch art: a real color-capable interactive
182
278
  * terminal. False under NO_COLOR (https://no-color.org — presence, not
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trawlme/cli",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "Trawl CLI — manage scraps from the terminal",
5
5
  "type": "module",
6
6
  "bin": {