@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.
- package/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/_index.d.ts +1 -0
- package/bundle/typescript/src/commands/game/_index.js +1 -0
- package/bundle/typescript/src/commands/game/_index.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.d.ts +124 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js +487 -29
- package/bundle/typescript/src/commands/game/sideQuest/commands/backlog.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.d.ts +15 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +61 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/crew.js +4 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/crew.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/note.d.ts +73 -14
- package/bundle/typescript/src/commands/game/sideQuest/commands/note.js +150 -40
- package/bundle/typescript/src/commands/game/sideQuest/commands/note.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/review.d.ts +39 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/review.js +48 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/review.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +4 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +15 -1
- package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.d.ts +87 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js +320 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/repro-scene.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.d.ts +36 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +116 -3
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +8 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +48 -0
- package/bundle/typescript/src/commands/game/sideQuest/game.js +112 -13
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js +23 -0
- package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless.js +4 -1
- package/bundle/typescript/src/commands/game/sideQuest/headless.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +32 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +122 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/repro.d.ts +106 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/repro.js +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/repro.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/device-seed.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.d.ts +17 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js +250 -36
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-dump.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.d.ts +67 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js +99 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-review.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.d.ts +85 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.js +100 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog-vocab.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.d.ts +58 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js +82 -3
- package/bundle/typescript/src/commands/game/sideQuest/utilities/backlog.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.d.ts +13 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.js +22 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/commit-ref.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.d.ts +42 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.js +57 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/handoff.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.d.ts +36 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.js +48 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/identity.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.d.ts +68 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.js +147 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/repro-launch.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js +55 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-grid.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.d.ts +27 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.js +44 -11
- package/bundle/typescript/src/commands/game/sideQuest/utilities/room-view.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.d.ts +47 -2
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js +76 -8
- package/bundle/typescript/src/commands/game/sideQuest/utilities/shared-run.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +39 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/table-notes.d.ts +30 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/table-notes.js +46 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/table-notes.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js +46 -0
- package/bundle/typescript/src/commands/game/sideQuest-backlog.sub.cmd.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.d.ts +3 -1
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +269 -42
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/tools/log/log.class.d.ts +17 -0
- package/bundle/typescript/src/tools/log/log.class.js +30 -1
- package/bundle/typescript/src/tools/log/log.class.js.map +1 -1
- 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
|
|
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
|
-
*
|
|
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
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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":"AAAA,OAAO,EAAE,gBAAgB,
|
|
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;
|