@trawlme/cli 3.3.0 → 3.4.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.
@@ -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,49 +15,77 @@
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 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).
37
69
  */
38
70
  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: [
71
+ // calm resting face, both claws down, normal smile.
72
+ idle: [
46
73
  '..O...O..',
47
- '.BBBBBBBO', // right claw raised (cols 8, rows 1-2)
48
- '.BWKBKWBO',
49
74
  '.BBBBBBB.',
50
- 'OBPKKKPB.', // left claw resting (col 0, rows 4-5) + blush + mouth
51
- 'OBBBBBBB.',
75
+ '.BWKBKWB.',
76
+ '.BBBBBBB.',
77
+ 'OBPKBKPBO',
78
+ 'OBBBKBBBO',
52
79
  ],
53
- // 'thinking' = the idle/working pose: both claws resting low (rows 4-5).
54
- thinking: [
80
+ // idle pose + the cyan thinking-blip on the antenna tips (frame-toggled in
81
+ // `gridForState`) — the only animated static state.
82
+ working: [
55
83
  '..O...O..',
56
84
  '.BBBBBBB.',
57
85
  '.BWKBKWB.',
58
86
  '.BBBBBBB.',
59
- 'OBPKKKPBO',
60
- 'OBBBBBBBO',
87
+ 'OBPKBKPBO',
88
+ 'OBBBKBBBO',
61
89
  ],
62
90
  // both claws raised (rows 1-2) + a big open mouth.
63
91
  celebrating: [
@@ -65,10 +93,21 @@ const GRIDS = {
65
93
  'OBBBBBBBO',
66
94
  'OBWKBKWBO',
67
95
  '.BBBBBBB.',
68
- '.BKKKKKB.',
96
+ '.BKBBBKB.',
97
+ '.BBKKKBB.',
98
+ ],
99
+ // right claw raised (rows 1-2) + a thumb pixel poking up above it (row 0,
100
+ // col 8); left claw resting.
101
+ thumbsup: [
102
+ '..O...O.O',
103
+ '.BBBBBBBO',
104
+ '.BWKBKWBO',
69
105
  '.BBBBBBB.',
106
+ 'OBPKBKPB.',
107
+ 'OBBBKBBB.',
70
108
  ],
71
- // antennae drooped + spread, flat mouth (no K), claws resting.
109
+ // antennae drooped + spread, flat mouth (no K), claws resting. A '?' is
110
+ // appended beside the eye line by `renderPinch`.
72
111
  confused: [
73
112
  '.O.....O.',
74
113
  '.BBBBBBB.',
@@ -77,16 +116,75 @@ const GRIDS = {
77
116
  'OBPBBBPBO',
78
117
  'OBBBBBBBO',
79
118
  ],
119
+ // right claw raised (rows 1-2), left claw resting; base face.
120
+ wave: [
121
+ '..O...O..',
122
+ '.BBBBBBBO',
123
+ '.BWKBKWBO',
124
+ '.BBBBBBB.',
125
+ 'OBPKBKPB.',
126
+ 'OBBBKBBB.',
127
+ ],
128
+ // pink heart-eyes (P replaces the W+K pupils), claws resting, normal smile.
129
+ heart: [
130
+ '..O...O..',
131
+ '.BBBBBBB.',
132
+ '.BPPBPPB.',
133
+ '.BBBBBBB.',
134
+ 'OBPKBKPBO',
135
+ 'OBBBKBBBO',
136
+ ],
137
+ // closed eyes (flat K line, no white), antennae drooped + spread, flat
138
+ // mouth, claws resting — like confused but eyes shut and no '?'.
139
+ sleepy: [
140
+ '.O.....O.',
141
+ '.BBBBBBB.',
142
+ '.BKKBKKB.',
143
+ '.BBBBBBB.',
144
+ 'OBPBBBPBO',
145
+ 'OBBBBBBBO',
146
+ ],
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.
149
+ shocked: [
150
+ '..O...O..',
151
+ 'OBBBBBBBO',
152
+ 'OBWKBKWBO',
153
+ '.BBBBBBB.',
154
+ '.BBBKBBB.',
155
+ '.BBBBBBB.',
156
+ ],
80
157
  };
81
158
  const CAPTIONS = {
82
- wave: 'Pinch says hi.',
83
- thinking: 'Pinch is thinking…',
159
+ idle: 'Pinch is here.',
160
+ working: 'Pinch is working…',
84
161
  celebrating: 'Pinch is celebrating!',
162
+ thumbsup: 'Pinch approves!',
85
163
  confused: 'Pinch looks confused.',
164
+ wave: 'Pinch says hi.',
165
+ heart: 'Pinch loves it.',
166
+ sleepy: 'Pinch is sleepy…',
167
+ shocked: 'Pinch is shocked!',
86
168
  };
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) {
169
+ /** Antenna-tip cells (row 0) for the `working` cyan blip: cols 2 & 6. */
170
+ const ANTENNA_TIP_COLS = [2, 6];
171
+ /** Replace the chars at `indices` in `row` with `ch` — never mutates `row`. */
172
+ function setCells(row, indices, ch) {
173
+ const chars = row.split('');
174
+ for (const i of indices)
175
+ chars[i] = ch;
176
+ return chars.join('');
177
+ }
178
+ /** Look up the grid for `state`. `frame` only affects `working`: on even
179
+ * frames its antenna tips blip cyan (the thinking indicator), on odd frames
180
+ * they stay orange — a 2-frame pulse with no layout shift. Every other
181
+ * state's grid is static and ignores `frame`. */
182
+ function gridForState(state, frame) {
183
+ if (state === 'working' && frame % 2 === 0) {
184
+ const rows = [...GRIDS.working];
185
+ rows[0] = setCells(rows[0], ANTENNA_TIP_COLS, 'C');
186
+ return rows;
187
+ }
90
188
  return GRIDS[state];
91
189
  }
92
190
  const RESET = '\x1b[0m';
@@ -133,8 +231,8 @@ function renderGrid(rows) {
133
231
  * one-line caption. Pure — never touches process.env/stdout; callers must
134
232
  * gate on `pinchEnabled()` before printing the result.
135
233
  *
136
- * `frame` is accepted for signature stability but currently unused every
137
- * state's grid is static (see `gridForState`).
234
+ * `frame` only affects `working` (the cyan antenna-tip blip alternates every
235
+ * frame); every other state's grid is static.
138
236
  */
139
237
  export function renderPinch(state, frame = 0) {
140
238
  const grid = gridForState(state, frame);
@@ -149,9 +247,9 @@ export function renderPinch(state, frame = 0) {
149
247
  /**
150
248
  * #131 — the ART lines only (no caption), optionally COMPACT: trailing and
151
249
  * 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.
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).
155
253
  */
156
254
  export function renderPinchArt(state, opts = {}) {
157
255
  let grid = gridForState(state, 0);
@@ -172,11 +270,11 @@ export function renderPinchArt(state, opts = {}) {
172
270
  }
173
271
  /**
174
272
  * #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.
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.
178
276
  */
179
- export const WORKING_FRAMES = ['thinking', 'wave', 'celebrating', 'wave'];
277
+ export const WORKING_FRAMES = ['working', 'wave', 'celebrating', 'wave'];
180
278
  /**
181
279
  * True when it's safe to print Pinch art: a real color-capable interactive
182
280
  * 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.1",
4
4
  "description": "Trawl CLI — manage scraps from the terminal",
5
5
  "type": "module",
6
6
  "bin": {