atris 3.74.7 → 3.74.9

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/lib/gm-card.js CHANGED
@@ -17,6 +17,10 @@
17
17
  // line one plain line under the body (who has it, what came of a word)
18
18
  // count, label a deck card's place in the deck and its status
19
19
  // watch the page looks again for the next idea while this shows
20
+ // progress on the waiting card: [{ at, line }], the plain lines of the
21
+ // drafting so far, newest last (at is ms since 1970)
22
+ // started_at on the waiting card: when that drafting began (ms since 1970)
23
+ // waited_ms on the waiting card: how long ago that was, read on the Mac
20
24
  //
21
25
  // A reply is a new card with a new id; nothing is ever patched in place.
22
26
  // A card's id carries a hash of its words and options (stamp), so options
@@ -32,7 +36,7 @@
32
36
  const crypto = require('node:crypto');
33
37
  const hash8 = x => crypto.createHash('sha256').update(JSON.stringify(x)).digest('hex').slice(0, 8);
34
38
 
35
- const KINDS = new Set(['idea', 'question', 'report', 'choice', 'yes', 'done', 'wait', 'reply', 'started', 'team', 'member', 'deck', 'swap']);
39
+ const KINDS = new Set(['idea', 'question', 'report', 'choice', 'yes', 'done', 'wait', 'missed', 'reply', 'started', 'team', 'member', 'deck', 'swap']);
36
40
  const STYLES = new Set(['primary', 'choice', 'option', 'quiet']);
37
41
  const SAY = { label: 'or say something', placeholder: 'say something', action: 'say', max: 280 };
38
42
 
@@ -72,7 +76,22 @@ const nav = o => ({ style: 'quiet', ...o, nav: true });
72
76
 
73
77
  const sayInput = (over = {}) => ({ ...SAY, ...over });
74
78
 
75
- function idea({ id, title, body, line = null, unstarted = null }) {
79
+ // concern: no draft passed every check in time, so this is the best one, with
80
+ // the second look's worry as its line, and the owner goes with it, has it
81
+ // sharpened, or asks for something else
82
+ function idea({ id, title, body, line = null, unstarted = null, concern = null }) {
83
+ if (concern) {
84
+ return {
85
+ id, kind: 'idea', asks: id, title, body,
86
+ line: concern,
87
+ options: [
88
+ answer(id, { id: 'do', label: 'go with it', action: 'do', style: 'primary', confirm: 'tap again to start' }),
89
+ answer(id, { id: 'sharper', label: 'sharpen it', action: 'sharper' }),
90
+ answer(id, { id: 'other', label: 'something else', action: 'next' }),
91
+ ],
92
+ input: sayInput(),
93
+ };
94
+ }
76
95
  return {
77
96
  id, kind: 'idea', asks: id, title, body,
78
97
  line: line || unstarted || null,
@@ -139,8 +158,21 @@ function done({ id, title, body, job = null }) {
139
158
  return { id, kind: 'done', asks: id, title, body, job, options: [answer(id, { id: 'nice', label: 'nice', action: 'nice', style: 'primary' })], input: sayInput() };
140
159
  }
141
160
 
142
- function wait({ id }) {
143
- return { id, kind: 'wait', asks: id, title: 'writing your next idea.', body: null, options: [], input: sayInput(), watch: true };
161
+ // progress, started_at, waited_ms: how the page shows the drafting is alive;
162
+ // none of them is in the stamp, so the card keeps its id while they change.
163
+ // Its box stays open: words typed there are a note for the idea being
164
+ // written, and thread is those notes with the answer to them.
165
+ function wait({ id, progress = [], started_at = null, waited_ms = null, thread = [] }) {
166
+ return { id, kind: 'wait', asks: id, title: 'writing your next idea.', body: null, options: [], input: sayInput({ placeholder: 'add a note for this idea' }), watch: true, progress, started_at, waited_ms, thread };
167
+ }
168
+
169
+ // the wait ended with nothing usable: a way to try again, and the box
170
+ function missed({ id }) {
171
+ return {
172
+ id, kind: 'missed', asks: id, title: 'no idea came together this time.', body: 'try again, or say what you want one about.',
173
+ options: [answer(id, { id: 'again', label: 'try again', action: 'next', style: 'primary' })],
174
+ input: sayInput(),
175
+ };
144
176
  }
145
177
 
146
178
  // A reply to words said on a card. When it asks its own question (it ends
@@ -324,6 +356,7 @@ function cardProblems(card) {
324
356
  const read = [['title', card.title], ['body', card.body], ['line', card.line], ...options.flatMap(o => [[`option ${o.id}`, o.label], [`option ${o.id} detail`, o.detail], [`option ${o.id} group`, o.group]])];
325
357
  if (card.input) read.push(['box', card.input.label], ['box', card.input.placeholder]);
326
358
  if (card.table) for (const row of card.table.rows) for (const cell of row) read.push(['table', cell]);
359
+ for (const p of Array.isArray(card.progress) ? card.progress : []) read.push(['progress', p && p.line]);
327
360
  for (const [where, text] of read) if (text && !isPlain(text)) out.push(`the ${where} has a command, flag, or path in it: ${String(text).slice(0, 80)}`);
328
361
  // a yes card says yes, no, and not now, and each binds the request it shows
329
362
  const asksYes = card.kind === 'yes' || (card.kind === 'deck' && card.request) || (card.kind === 'reply' && card.request && options.some(o => o.action === 'yes'));
@@ -367,6 +400,7 @@ function enforce(raw, report = () => {}) {
367
400
  const fixed = { ...card, title: plainWords(card.title) || 'next', body: card.body && plainWords(card.body), line: card.line && plainWords(card.line) };
368
401
  fixed.options = (card.options || []).filter(o => o.nav || o.answers === card.asks).map(o => ({ ...o, label: plainWords(o.label), ...(o.detail ? { detail: plainWords(o.detail) } : {}) }));
369
402
  if (fixed.table) fixed.table = { ...fixed.table, rows: fixed.table.rows.map(row => row.map(plainWords)) };
403
+ if (Array.isArray(fixed.progress)) fixed.progress = fixed.progress.map(p => ({ ...p, line: plainWords(p && p.line) }));
370
404
  if (!fixed.options.length && !fixed.input) fixed.options = [nav({ id: 'next', label: 'next', action: 'next' })];
371
405
  return fixed;
372
406
  }
@@ -391,6 +425,12 @@ function wire(card) {
391
425
  table: card.table || null,
392
426
  };
393
427
  for (const k of ['thread', 'line', 'count', 'label', 'time', 'watch']) if (card[k] !== undefined && card[k] !== null && !(Array.isArray(card[k]) && !card[k].length)) out[k] = card[k];
428
+ // the waiting card always says how far along it is, even before the first line
429
+ if (card.kind === 'wait') {
430
+ out.progress = Array.isArray(card.progress) ? card.progress.map(p => ({ at: p.at, line: p.line })) : [];
431
+ if (Number.isFinite(card.started_at)) out.started_at = card.started_at;
432
+ if (Number.isFinite(card.waited_ms)) out.waited_ms = card.waited_ms;
433
+ }
394
434
  return out;
395
435
  }
396
436
 
@@ -423,6 +463,7 @@ module.exports = {
423
463
  yes,
424
464
  done,
425
465
  wait,
466
+ missed,
426
467
  reply,
427
468
  team,
428
469
  member,