@impeccable/reviews 0.1.22 → 0.1.24

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/dist/ui/look.js CHANGED
@@ -9,7 +9,6 @@ import { fitsTask, taskInProgress, workStarted } from '../stages.js';
9
9
  * the box on the right. Only the middle changes from screen to screen.
10
10
  */
11
11
  export const PRODUCT = 'Impeccable for PRs';
12
- export const FEEDBACK = 'support@renaissance-geek.ai';
13
12
  /** How long the outro waits for a key before it closes itself (screens.ts), which its fine print says. */
14
13
  export const CLOSES_AFTER_MINUTES = 20;
15
14
  /** The box fills the terminal up to this size, then sits in the middle of it. */
@@ -80,7 +79,8 @@ function dotRows(word, max) {
80
79
  /** A paragraph of plain text wrapped to at most `max` columns: a sentence a line when each fits, else lines as even as the words allow. */
81
80
  function balanced(given, max) {
82
81
  const text = given.split(' ').map((word) => dotRows(word, max).join('\n')).join(' ');
83
- const sentences = text.split(/(?<=[.!?])\s+/);
82
+ // A sentence ends on a mark after its last word: the "!" a warning opens with is no sentence of its own.
83
+ const sentences = text.split(/(?<=\S[.!?])\s+/);
84
84
  if (sentences.length > 1 && sentences.every((line) => visibleWidth(line) <= max))
85
85
  return sentences;
86
86
  const lines = wrapTextWithAnsi(text, Math.max(10, max));
@@ -194,7 +194,7 @@ function questionPage(qv, inner, st) {
194
194
  ways: [[q.confirmLabel ?? 'Continue', 'Enter'], [q.skipLabel ?? 'Skip', 'Esc']],
195
195
  };
196
196
  }
197
- // One test account: both fields under the divider, each in a box with its label in the top edge, the password as dots.
197
+ // One account: its prompt under the title, then the hint and both fields under the divider, each field in a box with its label in the top edge, the second as dots. A test account of the app's sign-in (no fields of its own) leaves its prompt to the web page and its prompt's row blank, so its title stands alone where a one-line prompt would put the divider (#409).
198
198
  if (q.kind === 'account') {
199
199
  const width = Math.min(FIELD_WIDTH, inner);
200
200
  const label = (text) => ` ${st.soft(text)}`;
@@ -203,7 +203,7 @@ function questionPage(qv, inner, st) {
203
203
  const fields = [...fieldBox(first, qv.field(width - 2), width, qv.focus !== 1, st), ...fieldBox(second, qv.password?.() ?? '', width, qv.focus === 1, st)];
204
204
  return {
205
205
  heading: q.title ?? 'A test account',
206
- text: said(q.prompt, inner, st),
206
+ text: q.fields ? said(q.prompt, inner, st) : [''],
207
207
  rule: divider(inner, st),
208
208
  action: [...block([...hint, ...fields], inner, width), ...note],
209
209
  at: hint.length + (qv.focus === 1 ? 4 : 1),
@@ -315,10 +315,11 @@ function outroPage(scene, inner, st) {
315
315
  rule: divider(inner, st),
316
316
  action: [...block(notes, inner), ...(notes.length && links.length ? [''] : []), ...links, ...(outro.links.length === 1 ? [scene.copied ? center(st.soft('Copied to clipboard!'), inner) : copyWay(inner, st)] : [])],
317
317
  ways: scene.leaving ? undefined : [['Close', 'Enter']],
318
- foot: outro.outcome === 'stopped' ? [center(st.faint(`Questions? Write to ${FEEDBACK}`), inner)] : closesItself(scene, inner, st),
318
+ // A stopped run's foot is empty: no line to write to us in the closed beta (#413).
319
+ foot: outro.outcome === 'stopped' ? [] : closesItself(scene, inner, st),
319
320
  };
320
321
  }
321
- /** The outro's fine print that it closes on its own, until it is closing; a stopped run's foot keeps the way to write to us instead, one line either way. */
322
+ /** The outro's fine print that it closes on its own, until it is closing; a stopped run's has none. */
322
323
  const closesItself = (scene, inner, st) => (scene.leaving ? [] : [center(st.faint(`Closes on its own after ${CLOSES_AFTER_MINUTES} minutes.`), inner)]);
323
324
  function pageOf(f, inner) {
324
325
  const st = f.style;
@@ -390,9 +391,9 @@ function stack(page, inner, rows, st, scroll) {
390
391
  mark = [];
391
392
  if (over() > 0)
392
393
  rule = [];
393
- // Past this point a question's prompt scrolls with its field or choices, a blank row under it.
394
- const lead = over() > 0 && page.asks ? [...text, ''] : [];
395
- if (lead.length)
394
+ // Past this point a question's prompt scrolls with its field or choices, a blank row under it; an account's blank prompt row goes.
395
+ const lead = over() > 0 && page.asks && text.some(Boolean) ? [...text, ''] : [];
396
+ if (over() > 0)
396
397
  text = [];
397
398
  const action = windowed([...lead, ...page.action], page.action.length - over(), lead.length + (page.at ?? 0), scroll, inner, st);
398
399
  const parts = [mark, heading, text, rule, action, ways, foot].filter((part) => part.length);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impeccable/reviews",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Set up a repository for Impeccable for PRs from your terminal.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "private": false,