@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/fence.js +40 -4
- package/dist/focus.js +17 -0
- package/dist/host-questions.js +2 -2
- package/dist/main.js +27 -10
- package/dist/playbook/cases/cloudflare-previews.md +1 -1
- package/dist/playbook/cases/monorepo.md +5 -5
- package/dist/playbook/cases/netlify-setup.md +3 -3
- package/dist/playbook/cases/preview-protection.md +3 -2
- package/dist/playbook/cases/server-previews.md +3 -3
- package/dist/playbook/cases/sign-in.md +8 -8
- package/dist/playbook/cases/vercel-setup.md +3 -3
- package/dist/playbook.js +18 -3
- package/dist/pr-summary.js +45 -0
- package/dist/preflight.js +2 -1
- package/dist/tools.js +233 -54
- package/dist/ui/look.js +10 -9
- package/package.json +1 -1
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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);
|