@maka/maka-cli 5.65.2 → 5.67.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.
Files changed (95) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/_index.d.ts +1 -0
  3. package/bundle/typescript/src/commands/game/_index.js +1 -0
  4. package/bundle/typescript/src/commands/game/_index.js.map +1 -1
  5. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.d.ts +124 -0
  6. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js +487 -29
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js.map +1 -1
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.d.ts +15 -1
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +61 -4
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/crew.js +4 -1
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/crew.js.map +1 -1
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/note.d.ts +73 -14
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/note.js +150 -40
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/note.js.map +1 -1
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/review.d.ts +39 -0
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/review.js +48 -0
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/review.js.map +1 -0
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +4 -1
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
  21. package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
  22. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +15 -1
  23. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
  24. package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.d.ts +87 -0
  25. package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js +320 -0
  26. package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js.map +1 -0
  27. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +36 -0
  28. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +116 -3
  29. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
  30. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +8 -1
  31. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
  32. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +48 -0
  33. package/bundle/typescript/src/commands/game/sideQuest/game.js +112 -13
  34. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  35. package/bundle/typescript/src/commands/game/sideQuest/headless-harness.d.ts +12 -0
  36. package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js +23 -0
  37. package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js.map +1 -1
  38. package/bundle/typescript/src/commands/game/sideQuest/headless.js +4 -1
  39. package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
  40. package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +32 -0
  41. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +122 -3
  42. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  43. package/bundle/typescript/src/commands/game/sideQuest/types/repro.d.ts +106 -0
  44. package/bundle/typescript/src/commands/game/sideQuest/types/repro.js +2 -0
  45. package/bundle/typescript/src/commands/game/sideQuest/types/repro.js.map +1 -0
  46. package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.d.ts +12 -0
  47. package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +9 -0
  48. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  49. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.d.ts +17 -1
  50. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js +250 -36
  51. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js.map +1 -1
  52. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.d.ts +67 -1
  53. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js +99 -0
  54. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js.map +1 -1
  55. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.d.ts +85 -0
  56. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.js +100 -0
  57. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.js.map +1 -0
  58. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.d.ts +58 -3
  59. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js +82 -3
  60. package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js.map +1 -1
  61. package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.d.ts +13 -0
  62. package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.js +22 -0
  63. package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.js.map +1 -0
  64. package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.d.ts +42 -0
  65. package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.js +57 -0
  66. package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.js.map +1 -0
  67. package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.d.ts +36 -0
  68. package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.js +48 -0
  69. package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.js.map +1 -0
  70. package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.d.ts +68 -0
  71. package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.js +147 -0
  72. package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.js.map +1 -0
  73. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js +55 -1
  74. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js.map +1 -1
  75. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.d.ts +27 -1
  76. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.js +44 -11
  77. package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.js.map +1 -1
  78. package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.d.ts +47 -2
  79. package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js +76 -8
  80. package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js.map +1 -1
  81. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +39 -0
  82. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
  83. package/bundle/typescript/src/commands/game/sideQuest/utilities/table-notes.d.ts +30 -0
  84. package/bundle/typescript/src/commands/game/sideQuest/utilities/table-notes.js +46 -0
  85. package/bundle/typescript/src/commands/game/sideQuest/utilities/table-notes.js.map +1 -0
  86. package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.d.ts +1 -0
  87. package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js +46 -0
  88. package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js.map +1 -0
  89. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.d.ts +3 -1
  90. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +269 -42
  91. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  92. package/bundle/typescript/src/tools/log/log.class.d.ts +17 -0
  93. package/bundle/typescript/src/tools/log/log.class.js +30 -1
  94. package/bundle/typescript/src/tools/log/log.class.js.map +1 -1
  95. package/package.json +1 -1
@@ -1,35 +1,193 @@
1
1
  import { Log } from '../../../../tools/log/log.class.js';
2
2
  import { fetchBacklog, BACKLOG_STATUSES } from './backlog.js';
3
+ import { statusLabel, verdictLabel, boardPrintOrder } from './backlog-vocab.js';
4
+ import { commitMatches } from './commit-ref.js';
3
5
  /**
4
- * `maka play:shadowrun --backlog [--filter <status>]`.
6
+ * `maka play:shadowrun:backlog [<id>] [--filter <status>] [--commit <sha>]`.
5
7
  *
6
8
  * The out-of-game half of the backlog: read the board without starting
7
9
  * a session. Lives in its own module so the launcher's top-of-handler
8
10
  * branch can import it lazily and touch none of the game graph.
9
11
  *
10
- * Plain Log output, not blessed -- there is no screen here.
12
+ * REWRITTEN 2026-08-28 on a player complaint with two halves, both
13
+ * true: "1) It's all one color, and extremely hard to read. 2) there
14
+ * are no IDs."
15
+ *
16
+ * The colour half had one line of cause -- every row went through
17
+ * Log.info, so 125 items came out as a single cyan wall in which a done
18
+ * item, an open bug and a rulebook citation looked identical. Rows are
19
+ * now composed from Log.colors and printed with Log.plain, and the
20
+ * labels come from utilities/backlog-vocab so the in-game board and
21
+ * this one cannot drift about what a status is called.
22
+ *
23
+ * The ID half was worse, because nothing was ever missing on the wire:
24
+ * the /list route projects `fields: { reporterUserId: 0 }`, an
25
+ * EXCLUSION, so `_id` has been arriving since the board shipped and
26
+ * this file simply never printed it. An item you cannot name is an item
27
+ * you cannot act on -- and `--repro <id>` makes that literal.
11
28
  */
29
+ /** Chalk for a shared tone. `dim` is for genuinely secondary metadata
30
+ * only -- who, when, which session. Never the id, which is the thing a
31
+ * reader came here to copy. */
32
+ function ink(tone) {
33
+ const c = Log.colors;
34
+ switch (tone) {
35
+ case 'good': return c.success;
36
+ case 'bad': return c.error;
37
+ case 'warn': return c.warn;
38
+ case 'alert': return c.majestic;
39
+ case 'info': return c.notice;
40
+ default: return c.header;
41
+ }
42
+ }
43
+ const SEP = ' - ';
12
44
  function verdictLine(item) {
13
45
  const v = item.vetting;
14
46
  if (!v || v.state === 'pending')
15
- return 'checking the books...';
47
+ return Log.colors.header('checking the books...');
16
48
  if (v.state === 'failed')
17
- return "the books didn't answer";
49
+ return Log.colors.header("the books didn't answer");
18
50
  if (!v.verdict)
19
51
  return undefined;
20
- const label = v.verdict === 'canon-violation' ? 'breaks the rules'
21
- : v.verdict === 'bug' ? 'bug'
22
- : v.verdict === 'enhancement' ? 'wants building'
23
- : v.verdict === 'works-as-intended' ? 'working as meant'
24
- : 'needs detail';
25
- return `${label}${v.justification ? `: ${v.justification}` : ''}`;
52
+ const { label, tone } = verdictLabel(v.verdict);
53
+ return `${ink(tone)(`${label}:`)}${v.justification ? ` ${v.justification}` : ''}`;
54
+ }
55
+ function whenOf(item) {
56
+ return item.createdAt
57
+ ? new Date(item.createdAt).toISOString().slice(0, 16).replace('T', ' ')
58
+ : undefined;
59
+ }
60
+ /**
61
+ * The counts, so a 125-row board opens with orientation rather than a
62
+ * wall.
63
+ *
64
+ * ORDERED BY FIRST APPEARANCE, which is to say by the order the SERVER
65
+ * sorted the rows into -- in-review, then open. Not by a rank declared
66
+ * here.
67
+ *
68
+ * The first cut walked BACKLOG_STATUSES instead, so the summary read
69
+ * "40 open ... 7 in-review" above a list that led with in-review. A
70
+ * header that disagrees with the list under it is a small lie, and it
71
+ * is the same lie in miniature as the one this whole change is fixing:
72
+ * two places deciding independently what matters most. Deriving the
73
+ * order from the data means there is only ever one decision, taken on
74
+ * the server, and this cannot drift from it.
75
+ */
76
+ function summaryLine(items) {
77
+ const counts = new Map();
78
+ for (const it of items)
79
+ counts.set(it.status, (counts.get(it.status) ?? 0) + 1);
80
+ const parts = [];
81
+ for (const [status, n] of counts) {
82
+ parts.push(ink(statusLabel(status).tone)(`${n} ${status}`));
83
+ }
84
+ return parts.join(Log.colors.header(SEP));
85
+ }
86
+ /** One row: the status, the id you copy, and the sentence somebody
87
+ * wrote. Everything else indents under it and reads dimmer. */
88
+ function renderRow(item) {
89
+ const { label, tone } = statusLabel(item.status);
90
+ // THE ID IS THE POINT OF THIS LINE, so it takes the brightest ink on
91
+ // the row -- whiteBright in dark mode, black in light. Never `header`:
92
+ // a dim gray id is one nobody can pick out to select, and this
93
+ // codebase has already shipped one illegible gray in front of a
94
+ // player.
95
+ Log.plain(` ${ink(tone)(label)} ${Log.colors.bright(item._id)}`);
96
+ Log.plain(` ${item.text}`);
97
+ const who = [item.runnerName, item.reporterHandle].filter(Boolean).join(' / ');
98
+ const meta = [who, whenOf(item), item.sessionId ? `session ${item.sessionId}` : undefined]
99
+ .filter(Boolean).join(SEP);
100
+ if (meta)
101
+ Log.plain(` ${Log.colors.header(meta)}`);
102
+ const verdict = verdictLine(item);
103
+ if (verdict)
104
+ Log.plain(` ${verdict}`);
105
+ const cites = (item.vetting?.citations ?? []).slice(0, 3)
106
+ .map(c => `${c.book} p.${c.page ?? '?'}${c.section ? ` (${c.section})` : ''}`);
107
+ if (cites.length)
108
+ Log.plain(` ${Log.colors.notice(cites.join('; '))}`);
109
+ // The evidence a closed item was really fixed. Short shas: the full 40
110
+ // tells the reader nothing extra and wraps the line.
111
+ const commits = item.commits ?? [];
112
+ if (commits.length) {
113
+ Log.plain(` ${Log.colors.notice(`fixed by ${commits.map(c => c.slice(0, 8)).join(', ')}`)}`);
114
+ }
115
+ // WHETHER THERE IS A BENCH, said on the row rather than discovered by
116
+ // typing the command and being turned away (user, 2026-08-28: "how do
117
+ // I know the repro has a bench?"). Green, because it is the only line
118
+ // here that is an action rather than a fact.
119
+ if (item.repro?.steps?.length) {
120
+ Log.plain(` ${Log.colors.success(`bench: maka play:shadowrun --repro ${item._id}`)}`);
121
+ }
26
122
  }
27
- export async function dumpBacklog(filter) {
123
+ /** One item in full -- nothing truncated, every citation, every sha.
124
+ * The view you open when you are about to go and check it. */
125
+ function renderFull(item) {
126
+ const { label, tone } = statusLabel(item.status);
127
+ Log.plain('');
128
+ Log.plain(`${ink(tone)(label)} ${Log.colors.bright(item._id)}`);
129
+ Log.plain('');
130
+ Log.plain(` ${item.text}`);
131
+ Log.plain('');
132
+ const who = [item.runnerName, item.reporterHandle].filter(Boolean).join(' / ');
133
+ const meta = [who, whenOf(item)].filter(Boolean).join(SEP);
134
+ if (meta)
135
+ Log.plain(` ${Log.colors.header(meta)}`);
136
+ if (item.sessionId)
137
+ Log.plain(` ${Log.colors.header(`session ${item.sessionId}`)}`);
138
+ const build = [
139
+ item.cliVersion ? `cli ${item.cliVersion}` : undefined,
140
+ item.engineVersion ? `engine ${item.engineVersion}` : undefined,
141
+ item.platform,
142
+ ].filter(Boolean).join(SEP);
143
+ if (build)
144
+ Log.plain(` ${Log.colors.header(build)}`);
145
+ const verdict = verdictLine(item);
146
+ if (verdict) {
147
+ Log.plain('');
148
+ Log.plain(` ${verdict}`);
149
+ }
150
+ for (const c of item.vetting?.citations ?? []) {
151
+ Log.plain(` ${Log.colors.notice(`${c.book} p.${c.page ?? '?'}${c.section ? ` (${c.section})` : ''}`)}`);
152
+ }
153
+ const commits = item.commits ?? [];
154
+ if (commits.length) {
155
+ Log.plain('');
156
+ Log.plain(` ${Log.colors.notice('fixed by')}`);
157
+ for (const sha of commits)
158
+ Log.plain(` ${Log.colors.notice(sha)}`);
159
+ }
160
+ const repro = item.repro;
161
+ if (repro?.steps?.length) {
162
+ Log.plain('');
163
+ Log.plain(` ${Log.colors.success('REPRO BENCH')}`);
164
+ if (repro.premise)
165
+ Log.plain(` ${repro.premise}`);
166
+ repro.steps.forEach((step, i) => Log.plain(` ${i + 1}. ${step}`));
167
+ if (repro.expect)
168
+ Log.plain(` ${Log.colors.header(`passing looks like: ${repro.expect}`)}`);
169
+ Log.plain(` ${Log.colors.success(`maka play:shadowrun --repro ${item._id}`)}`);
170
+ }
171
+ Log.plain('');
172
+ }
173
+ export async function dumpBacklog(opts = {}) {
174
+ const { filter, commit, id, all, close, reason } = opts;
28
175
  if (filter && !BACKLOG_STATUSES.includes(filter)) {
29
176
  Log.error(`No status called "${filter}". One of: ${BACKLOG_STATUSES.join(', ')}.`);
30
177
  return;
31
178
  }
32
- const { outcome, items } = await fetchBacklog(filter);
179
+ // A TARGETED LOOKUP ALWAYS SEARCHES EVERYTHING. Asking for one thing
180
+ // by name and being told it does not exist -- because it is finished
181
+ // -- is the worst answer available.
182
+ //
183
+ // `--commit` belongs here as much as an id, and leaving it out was a
184
+ // real regression from hiding closed items by default: that flag
185
+ // exists to answer "what did this change close?", and closed is
186
+ // exactly what the default view hides. The question that motivated
187
+ // the whole feature -- finding the item fixed by 359ad1fe -- stopped
188
+ // working the moment that item was signed off.
189
+ const targeted = !!id || !!commit;
190
+ const { outcome, items } = await fetchBacklog(filter, { all: all || targeted });
33
191
  if (outcome === 'no-login') {
34
192
  Log.error('The backlog runs on your maka-cli.com login -- run `maka login` first.');
35
193
  return;
@@ -46,33 +204,89 @@ export async function dumpBacklog(filter) {
46
204
  Log.error("maka-cli.com isn't answering -- the backlog is offline right now.");
47
205
  return;
48
206
  }
49
- if (items.length === 0) {
50
- Log.info(filter ? `Nothing ${filter} on the board.` : 'The backlog is empty.');
207
+ // ONE ITEM, IN FULL. Matched on the WHOLE id, not a prefix: a
208
+ // truncated backlog id in an API call has already cost a session a
209
+ // 404, and every view that prints an id prints all of it. There is
210
+ // nothing to abbreviate here, so there is nothing to get wrong.
211
+ if (id) {
212
+ const found = items.find(it => it._id === id);
213
+ if (!found) {
214
+ Log.error(`No item with id "${id}" on the board${filter ? ` in ${filter}` : ''}.`);
215
+ Log.info('`maka play:shadowrun --backlog` lists them -- every row carries its id.');
216
+ return;
217
+ }
218
+ if (close) {
219
+ const { postBacklogClose } = await import("./backlog.js");
220
+ const outcome = await postBacklogClose(found._id, (reason ?? "").trim());
221
+ if (outcome === "forbidden") {
222
+ Log.error("That one is not yours to close -- only the play-tester who filed it, or an admin.");
223
+ return;
224
+ }
225
+ if (outcome !== "ok") {
226
+ Log.error("Could not close it: " + outcome);
227
+ return;
228
+ }
229
+ Log.success("Closed: " + found.text.slice(0, 70));
230
+ Log.plain(Log.colors.header(" Off the board as wont-fix, with your reason on the record."));
231
+ return;
232
+ }
233
+ renderFull(found);
51
234
  return;
52
235
  }
53
- Log.info(`BACKLOG -- ${items.length} item${items.length === 1 ? '' : 's'}${filter ? ` (${filter})` : ''}`);
54
- for (const item of items) {
55
- Log.info('');
56
- Log.info(`[${item.status}] ${item.text}`);
57
- const who = [item.runnerName, item.reporterHandle].filter(Boolean).join(' / ');
58
- const when = item.createdAt ? new Date(item.createdAt).toISOString().slice(0, 16).replace('T', ' ') : undefined;
59
- if (who || when)
60
- Log.info(` ${[who, when].filter(Boolean).join(' ')}`);
61
- if (item.sessionId)
62
- Log.info(` session ${item.sessionId}`);
63
- const verdict = verdictLine(item);
64
- if (verdict)
65
- Log.info(` ${verdict}`);
66
- // The evidence a closed item was really fixed. Short shas: the full
67
- // 40 tells the reader nothing extra and wraps the line.
68
- const commits = item.commits ?? [];
69
- if (commits.length > 0) {
70
- Log.info(` fixed by ${commits.map(c => c.slice(0, 8)).join(', ')}`);
236
+ const shown = commit ? items.filter(it => commitMatches(it.commits, commit)) : items;
237
+ if (shown.length === 0) {
238
+ if (commit) {
239
+ Log.info(`Nothing on the board was closed by "${commit}".`);
240
+ return;
71
241
  }
72
- const cites = (item.vetting?.citations ?? []).slice(0, 3)
73
- .map(c => `${c.book} p.${c.page ?? '?'}${c.section ? ` (${c.section})` : ''}`);
74
- for (const c of cites)
75
- Log.info(` ${c}`);
242
+ Log.info(filter ? `Nothing ${filter} on the board.` : 'The backlog is empty.');
243
+ return;
244
+ }
245
+ const scope = [filter, commit ? `commit ${commit}` : undefined].filter(Boolean).join(', ');
246
+ Log.plain('');
247
+ Log.plain(Log.colors.bright(`BACKLOG -- ${shown.length} item${shown.length === 1 ? '' : 's'}${scope ? ` (${scope})` : ''}`));
248
+ Log.plain('');
249
+ // PRINTED LOWEST-PRIORITY FIRST, so the rows that need you land at the
250
+ // BOTTOM -- closest to the prompt, which is where a scrolling terminal
251
+ // actually leaves your eye.
252
+ //
253
+ // The server sorts in-review first and that is right: it is the order
254
+ // a caller iterates, and the summary above reads left-to-right in it.
255
+ // But PRINTING that order top-down buries the urgent rows off the top
256
+ // of the screen and leaves wont-fix under the cursor, which is exactly
257
+ // what happened here (user, 2026-08-28, on seeing four [wont] rows and
258
+ // nothing else: "So the list is backwards").
259
+ //
260
+ // This is the SAME ruling as reviewDisplayOrder in backlog-review.ts,
261
+ // made yesterday about the review queue, and this list repeated the
262
+ // mistake it was written to fix. Reversing at the point of PRINT --
263
+ // never in the data -- is what keeps the two facts separate: the
264
+ // server's order is the priority, this is only which end of it you
265
+ // read first.
266
+ for (const item of boardPrintOrder(shown)) {
267
+ renderRow(item);
268
+ Log.plain('');
269
+ }
270
+ // The counts move DOWN here for the same reason: at the top of a
271
+ // 52-row list they scroll away unread.
272
+ const tail = summaryLine(shown);
273
+ if (tail)
274
+ Log.plain(` ${tail}`);
275
+ // SAY WHAT IS NOT SHOWN. A filtered view that does not admit it is
276
+ // filtered is how somebody concludes their item vanished.
277
+ // ...and NOT on a targeted lookup, which deliberately searched the
278
+ // closed items too. Saying they are hidden while one is on screen is
279
+ // a footer contradicting the list above it.
280
+ if (!filter && !all && !targeted) {
281
+ Log.plain(Log.colors.header(' Closed items are hidden -- "--all" for everything, "--filter complete" for just those.'));
282
+ }
283
+ Log.plain(Log.colors.header(' <id> reads one in full. --commit <sha> finds what a change closed. <id> --close <why> retracts it.'));
284
+ // The bench line is only worth printing when there IS one to reach.
285
+ // A footer advertising a route that nothing on screen offers reads
286
+ // as a broken feature rather than an absent one.
287
+ if (shown.some(it => it.repro?.steps?.length)) {
288
+ Log.plain(Log.colors.success(' --repro <id> plays the bench for a row marked "bench:" above.'));
76
289
  }
290
+ Log.plain('');
77
291
  }
78
292
  //# sourceMappingURL=backlog-dump.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"backlog-dump.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/backlog-dump.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backlog-dump.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/backlog-dump.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,8 @@
1
- import { IReviewItem, BacklogOutcome } from './backlog.js';
1
+ import { IReviewItem, IBacklogItem, BacklogOutcome } from './backlog.js';
2
+ export declare function rememberBoard(items: IBacklogItem[]): void;
3
+ /** 1-based, against the board as it was last PRINTED. */
4
+ export declare function boardItemAt(n: number): IBacklogItem | undefined;
5
+ export declare function boardSize(): number;
2
6
  /** Replace the rendered list. Called ONLY when a fresh queue is shown
3
7
  * to the player -- that is what makes the numbers theirs. */
4
8
  export declare function rememberQueue(items: IReviewItem[]): void;
@@ -63,3 +67,65 @@ export declare function isValidationRow(item: {
63
67
  kind?: string;
64
68
  status?: string;
65
69
  }): boolean;
70
+ /**
71
+ * THE PRINT ORDER, with each row's number already bound to it.
72
+ *
73
+ * Numbers are assigned in the BOARD's order (1 = the item the server
74
+ * listed first, which is also `reviewItemAt(1)`), and only then is the
75
+ * sequence reversed for printing. User ruling 2026-08-27: "REVERSE THE
76
+ * ORDER OF THE REVIEW ITEMS" -- a terminal scrolls, so the last line
77
+ * printed is the one actually read first, and printing 1..n put the
78
+ * HIGHEST number under the player's eye.
79
+ *
80
+ * THE TWO HALVES MUST NOT DRIFT. If the numbering were assigned after
81
+ * the reverse, the list would say 1 where the resolver means n, and an
82
+ * answer would post against the wrong item -- landing somewhere
83
+ * plausible enough that nobody notices. That is the one failure a
84
+ * numbered queue cannot have, so the binding is done here, once, and
85
+ * returned as a pair.
86
+ */
87
+ export declare function reviewDisplayOrder<T>(items: T[]): {
88
+ item: T;
89
+ n: number;
90
+ }[];
91
+ /**
92
+ * DOES THIS ANSWER REJECT THE FIX, and if so what is the reason?
93
+ *
94
+ * "backlog review 1 reject <why>" (user request 2026-08-27). Matched
95
+ * only as the FIRST word, so a reply that merely CONTAINS "reject" --
96
+ * "I reject nothing, looks good" -- cannot bounce a fix by accident.
97
+ * The asymmetry is the same one that keeps bare "yes" out of job
98
+ * acceptance: a wrongly-sent rejection reopens closed work and costs
99
+ * somebody a search for a bug that is not there, while a missed one
100
+ * costs a retype.
101
+ *
102
+ * Returns null when this is not a rejection. Returns the reason
103
+ * VERBATIM otherwise -- it is a human sentence, not arguments, and the
104
+ * next person fixing this has nothing else to work from.
105
+ */
106
+ export declare function parseRejection(text: string): string | null;
107
+ /**
108
+ * IS THIS ANSWER ASKING FOR THE BENCH, rather than answering at all?
109
+ *
110
+ * "backlog review 1 repro" drops into the repro scene for that item.
111
+ *
112
+ * RESERVED THE HARD WAY, after it cost a real sign-off. On 2026-08-28
113
+ * the reporter typed exactly that, on a validation row, against a verb
114
+ * that did not exist yet -- so `repro` fell through as the ANSWER, was
115
+ * posted as their confirmation, and closed item b9YeNqTNBJuk9dbrk.
116
+ *
117
+ * A sign-off is the one input in this flow that cannot be taken back
118
+ * from the client: it is what moves an item to complete, and the reject
119
+ * route refuses any item that already carries one.
120
+ *
121
+ * The lesson is not "add the verb". It is that on a validation row every
122
+ * UNRECOGNISED word is a permanent confirmation, so a word a player
123
+ * could reasonably believe is a command must be claimed BEFORE it is
124
+ * described to them anywhere -- and this one had already been written
125
+ * into a plan they read.
126
+ *
127
+ * Matched as the first word only, exactly like a rejection, so a
128
+ * confirmation that merely mentions it ("the repro looks right") still
129
+ * signs off.
130
+ */
131
+ export declare function parseReproRequest(text: string): boolean;
@@ -28,6 +28,36 @@ let answeredIds = new Set();
28
28
  /** Count from the background login probe, for the notice. -1 = unknown. */
29
29
  let pendingAtLogin = -1;
30
30
  let probing;
31
+ /**
32
+ * THE BOARD'S numbering, which is NOT the review queue's.
33
+ *
34
+ * In-game the board had no handles at all: rows carried neither an id
35
+ * nor a number, so there was nothing to name (player, 2026-08-28:
36
+ * "there isn't anything for me to target a review -- the IDs aren't
37
+ * there... Copy/paste is cumbersome in-game"). Ids are right for a
38
+ * terminal you can select text in and useless inside blessed.
39
+ *
40
+ * KEPT SEPARATE FROM THE REVIEW SNAPSHOT ON PURPOSE. They are different
41
+ * SETS -- the board is everything, the queue is only what waits on you
42
+ * -- so "3" cannot mean one row in both. Sharing one snapshot would
43
+ * make the number silently follow whichever list was rendered last,
44
+ * which is the one failure a numbered list must not have. The two are
45
+ * addressed by different verbs for the same reason: `backlog <n>` reads
46
+ * the board, `backlog review <n>` answers the queue.
47
+ */
48
+ let boardSnapshot = [];
49
+ export function rememberBoard(items) {
50
+ boardSnapshot = [...items];
51
+ }
52
+ /** 1-based, against the board as it was last PRINTED. */
53
+ export function boardItemAt(n) {
54
+ if (!Number.isInteger(n) || n < 1 || n > boardSnapshot.length)
55
+ return undefined;
56
+ return boardSnapshot[n - 1];
57
+ }
58
+ export function boardSize() {
59
+ return boardSnapshot.length;
60
+ }
31
61
  /** Replace the rendered list. Called ONLY when a fresh queue is shown
32
62
  * to the player -- that is what makes the numbers theirs. */
33
63
  export function rememberQueue(items) {
@@ -54,6 +84,7 @@ export function isReviewAnswered(id) {
54
84
  /** Only for tests and a fresh session. */
55
85
  export function resetReviewQueue() {
56
86
  snapshot = [];
87
+ boardSnapshot = [];
57
88
  answeredIds = new Set();
58
89
  pendingAtLogin = -1;
59
90
  probing = undefined;
@@ -134,4 +165,72 @@ export function isValidationRow(item) {
134
165
  return item.kind === 'validation';
135
166
  return item.status === 'complete' || item.status === 'in-review';
136
167
  }
168
+ /**
169
+ * THE PRINT ORDER, with each row's number already bound to it.
170
+ *
171
+ * Numbers are assigned in the BOARD's order (1 = the item the server
172
+ * listed first, which is also `reviewItemAt(1)`), and only then is the
173
+ * sequence reversed for printing. User ruling 2026-08-27: "REVERSE THE
174
+ * ORDER OF THE REVIEW ITEMS" -- a terminal scrolls, so the last line
175
+ * printed is the one actually read first, and printing 1..n put the
176
+ * HIGHEST number under the player's eye.
177
+ *
178
+ * THE TWO HALVES MUST NOT DRIFT. If the numbering were assigned after
179
+ * the reverse, the list would say 1 where the resolver means n, and an
180
+ * answer would post against the wrong item -- landing somewhere
181
+ * plausible enough that nobody notices. That is the one failure a
182
+ * numbered queue cannot have, so the binding is done here, once, and
183
+ * returned as a pair.
184
+ */
185
+ export function reviewDisplayOrder(items) {
186
+ return items.map((item, i) => ({ item, n: i + 1 })).reverse();
187
+ }
188
+ /**
189
+ * DOES THIS ANSWER REJECT THE FIX, and if so what is the reason?
190
+ *
191
+ * "backlog review 1 reject <why>" (user request 2026-08-27). Matched
192
+ * only as the FIRST word, so a reply that merely CONTAINS "reject" --
193
+ * "I reject nothing, looks good" -- cannot bounce a fix by accident.
194
+ * The asymmetry is the same one that keeps bare "yes" out of job
195
+ * acceptance: a wrongly-sent rejection reopens closed work and costs
196
+ * somebody a search for a bug that is not there, while a missed one
197
+ * costs a retype.
198
+ *
199
+ * Returns null when this is not a rejection. Returns the reason
200
+ * VERBATIM otherwise -- it is a human sentence, not arguments, and the
201
+ * next person fixing this has nothing else to work from.
202
+ */
203
+ export function parseRejection(text) {
204
+ const m = /^reject\b\s*([\s\S]*)$/i.exec(text.trim());
205
+ if (!m)
206
+ return null;
207
+ return m[1].trim();
208
+ }
209
+ /**
210
+ * IS THIS ANSWER ASKING FOR THE BENCH, rather than answering at all?
211
+ *
212
+ * "backlog review 1 repro" drops into the repro scene for that item.
213
+ *
214
+ * RESERVED THE HARD WAY, after it cost a real sign-off. On 2026-08-28
215
+ * the reporter typed exactly that, on a validation row, against a verb
216
+ * that did not exist yet -- so `repro` fell through as the ANSWER, was
217
+ * posted as their confirmation, and closed item b9YeNqTNBJuk9dbrk.
218
+ *
219
+ * A sign-off is the one input in this flow that cannot be taken back
220
+ * from the client: it is what moves an item to complete, and the reject
221
+ * route refuses any item that already carries one.
222
+ *
223
+ * The lesson is not "add the verb". It is that on a validation row every
224
+ * UNRECOGNISED word is a permanent confirmation, so a word a player
225
+ * could reasonably believe is a command must be claimed BEFORE it is
226
+ * described to them anywhere -- and this one had already been written
227
+ * into a plan they read.
228
+ *
229
+ * Matched as the first word only, exactly like a rejection, so a
230
+ * confirmation that merely mentions it ("the repro looks right") still
231
+ * signs off.
232
+ */
233
+ export function parseReproRequest(text) {
234
+ return /^repro\b/i.test(text.trim());
235
+ }
137
236
  //# sourceMappingURL=backlog-review.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"backlog-review.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/backlog-review.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backlog-review.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/backlog-review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * THE BOARD'S SHARED VOCABULARY -- what a status is called, what a
3
+ * verdict is called, and how loud each one is.
4
+ *
5
+ * Two surfaces render the backlog and they used to word it twice:
6
+ * `commands/backlog.ts` in-game (blessed tags) and
7
+ * `utilities/backlog-dump.ts` out of game (chalk, via Log). The labels
8
+ * were retyped in both, which is the shape of a fault this repo has
9
+ * already paid for -- the launcher's second copy of the status list
10
+ * refused `in-review` as a typo while the server had been writing it
11
+ * for a day (see sideQuest.sub.cmd.ts's note on its own duplication).
12
+ *
13
+ * WHAT IS SHARED IS THE VOCABULARY, NOT THE PAINT. A tone is a severity,
14
+ * not a colour: blessed and chalk have different palettes and different
15
+ * legibility problems, so each surface maps tone to its own ink. What
16
+ * neither surface gets to decide for itself is what an item is CALLED
17
+ * or how much it matters.
18
+ *
19
+ * Pure on purpose -- no Log, no blessed, no transport. The out-of-game
20
+ * dump is loaded lazily precisely so reading a list touches none of the
21
+ * game graph, and this module must not be the thing that drags it in.
22
+ */
23
+ /**
24
+ * THE STATUSES THEMSELVES, and this is where they live.
25
+ *
26
+ * Moved here from the transport 2026-08-28, and the move is the point:
27
+ * utilities/backlog.ts reaches cloud-saves -> persistence -> models, so
28
+ * anything importing the status list to render or validate a status was
29
+ * dragging the entire save graph behind it. That is how a second copy
30
+ * gets written -- the launcher has one, annotated as a duplicate it
31
+ * could not avoid "without chaining the whole game graph into every
32
+ * `maka` invocation" -- and that copy then drifted, refusing `in-review`
33
+ * as a typo for a day.
34
+ *
35
+ * A pure module carrying the vocabulary is what makes the duplicate
36
+ * unnecessary. backlog.ts re-exports these so no caller had to change.
37
+ */
38
+ export type BacklogStatus = 'open' | 'in-progress' | 'in-review' | 'complete' | 'wont-fix';
39
+ export declare const BACKLOG_STATUSES: BacklogStatus[];
40
+ /**
41
+ * THE PRINT ORDER: lowest priority first, so what needs you ends up at
42
+ * the BOTTOM -- closest to the prompt, which is where a scrolling
43
+ * terminal leaves your eye.
44
+ *
45
+ * The server sorts in-review first, and that is right for a caller
46
+ * iterating the list. It is wrong for PRINTING it, and the difference
47
+ * has now been reported three times about three different surfaces:
48
+ * the review queue ("REVERSE THE ORDER OF THE REVIEW ITEMS"), the
49
+ * out-of-game board ("So the list is backwards"), and the in-game one
50
+ * ("I see 'wont' items first"). Each was fixed where it was reported
51
+ * and nowhere else, so the same board read correctly in one place and
52
+ * backwards in the next.
53
+ *
54
+ * Lives here, with the other thing every surface must agree about.
55
+ * Reversal happens at the point of PRINT and never in the data: the
56
+ * server's priority order and which end a human reads first are two
57
+ * separate facts, and collapsing them is how a number would come to
58
+ * mean a different row than the one it labels.
59
+ *
60
+ * See reviewDisplayOrder in backlog-review.ts for the numbered variant
61
+ * of this same rule -- it binds each row's number BEFORE reversing,
62
+ * which is the invariant that keeps "review 1" pointing at row 1.
63
+ */
64
+ export declare function boardPrintOrder<T>(items: T[]): T[];
65
+ /** How loud, in the abstract. Each renderer picks its own ink. */
66
+ export type BacklogTone = 'good' | 'bad' | 'warn' | 'info' | 'alert' | 'dim';
67
+ export interface IBacklogLabel {
68
+ /** The bracketed tag, padded to a common width so rows line up. */
69
+ label: string;
70
+ tone: BacklogTone;
71
+ }
72
+ /** An unknown status renders as itself rather than as "open". A status
73
+ * this build has never heard of is news, and reporting it as the
74
+ * default hid exactly that: `in-review` shipped from the server and
75
+ * showed here as "[open]" -- an item awaiting the player's word drawn
76
+ * as one nobody had touched. */
77
+ export declare function statusLabel(status: string): IBacklogLabel;
78
+ /** Whether this status has a label of its own, rather than falling back
79
+ * to being echoed raw. Exists for the test that matters: every status
80
+ * the transport knows about must be named here. Asking that of
81
+ * statusLabel's OUTPUT cannot work -- "open" legitimately renders as
82
+ * "[open]", which is also the exact shape of the fallback, so the two
83
+ * are indistinguishable from outside. */
84
+ export declare function hasStatusLabel(status: string): boolean;
85
+ export declare function verdictLabel(verdict: string): IBacklogLabel;