mustflow 1.31.0 → 2.11.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 (64) hide show
  1. package/README.md +23 -9
  2. package/dist/cli/commands/classify.js +61 -6
  3. package/dist/cli/commands/contract-lint.js +13 -4
  4. package/dist/cli/commands/dashboard.js +6 -0
  5. package/dist/cli/commands/index.js +5 -0
  6. package/dist/cli/commands/run.js +4 -1
  7. package/dist/cli/commands/verify.js +488 -43
  8. package/dist/cli/i18n/en.js +61 -10
  9. package/dist/cli/i18n/es.js +61 -10
  10. package/dist/cli/i18n/fr.js +61 -10
  11. package/dist/cli/i18n/hi.js +61 -10
  12. package/dist/cli/i18n/ko.js +61 -10
  13. package/dist/cli/i18n/zh.js +61 -10
  14. package/dist/cli/lib/dashboard-export.js +62 -12
  15. package/dist/cli/lib/dashboard-html/client-script.js +1936 -0
  16. package/dist/cli/lib/dashboard-html/locale-bootstrap.js +8 -0
  17. package/dist/cli/lib/dashboard-html/styles.js +572 -0
  18. package/dist/cli/lib/dashboard-html/template.js +134 -0
  19. package/dist/cli/lib/dashboard-html/types.js +1 -0
  20. package/dist/cli/lib/dashboard-html.js +1 -1907
  21. package/dist/cli/lib/dashboard-locale.js +37 -0
  22. package/dist/cli/lib/local-index/constants.js +48 -0
  23. package/dist/cli/lib/local-index/index.js +2256 -0
  24. package/dist/cli/lib/local-index/sql.js +15 -0
  25. package/dist/cli/lib/local-index/types.js +1 -0
  26. package/dist/cli/lib/local-index.js +1 -1911
  27. package/dist/cli/lib/run-plan.js +76 -1
  28. package/dist/cli/lib/templates.js +18 -1
  29. package/dist/cli/lib/validation/command-intents.js +11 -0
  30. package/dist/cli/lib/validation/constants.js +238 -0
  31. package/dist/cli/lib/validation/index.js +1384 -0
  32. package/dist/cli/lib/validation/primitives.js +198 -0
  33. package/dist/cli/lib/validation/test-selection.js +95 -0
  34. package/dist/cli/lib/validation/types.js +1 -0
  35. package/dist/cli/lib/validation.js +1 -1770
  36. package/dist/core/check-issues.js +6 -0
  37. package/dist/core/completion-verdict.js +209 -0
  38. package/dist/core/contract-lint.js +221 -6
  39. package/dist/core/external-evidence.js +9 -0
  40. package/dist/core/public-json-contracts.js +21 -0
  41. package/dist/core/repeated-failure.js +17 -0
  42. package/dist/core/repro-evidence.js +53 -0
  43. package/dist/core/scope-risk.js +64 -0
  44. package/dist/core/skill-route-alignment.js +20 -0
  45. package/dist/core/source-anchor-status.js +4 -1
  46. package/dist/core/test-selection.js +3 -0
  47. package/dist/core/validation-ratchet.js +52 -0
  48. package/dist/core/verification-evidence.js +249 -0
  49. package/examples/README.md +12 -4
  50. package/package.json +1 -1
  51. package/schemas/README.md +13 -3
  52. package/schemas/change-verification-report.schema.json +16 -2
  53. package/schemas/commands.schema.json +4 -0
  54. package/schemas/contract-lint-report.schema.json +29 -0
  55. package/schemas/dashboard-export.schema.json +227 -0
  56. package/schemas/latest-run-pointer.schema.json +384 -0
  57. package/schemas/run-receipt.schema.json +4 -0
  58. package/schemas/test-selection.schema.json +81 -0
  59. package/schemas/verify-report.schema.json +361 -1
  60. package/schemas/verify-run-manifest.schema.json +410 -0
  61. package/templates/default/i18n.toml +1 -1
  62. package/templates/default/locales/en/.mustflow/skills/INDEX.md +124 -29
  63. package/templates/default/locales/en/.mustflow/skills/routes.toml +289 -0
  64. package/templates/default/manifest.toml +29 -2
@@ -0,0 +1,8 @@
1
+ import { getDashboardLocaleBundle } from '../dashboard-locale.js';
2
+ export function createDashboardLocaleBootstrap() {
3
+ const localeBundle = getDashboardLocaleBundle();
4
+ return {
5
+ serializedLocaleBundle: JSON.stringify(localeBundle),
6
+ serializedAvailableLocales: JSON.stringify(localeBundle.locales),
7
+ };
8
+ }
@@ -0,0 +1,572 @@
1
+ export function renderDashboardStyles() {
2
+ return `:root {
3
+ color-scheme: light dark;
4
+ --bg: #101216;
5
+ --panel: #181b21;
6
+ --line: #2a2f3a;
7
+ --text: #eef1f7;
8
+ --muted: #aeb6c5;
9
+ --accent: #8fb4ff;
10
+ --danger: #ff9a9a;
11
+ --ok: #9be7ba;
12
+ --row-bg: rgba(255, 255, 255, 0.018);
13
+ --row-bg-alt: rgba(255, 255, 255, 0.035);
14
+ --status-neutral-bg: rgba(174, 182, 197, 0.1);
15
+ --status-ok-bg: rgba(155, 231, 186, 0.1);
16
+ --status-warn-bg: rgba(255, 154, 154, 0.1);
17
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
18
+ }
19
+ * { box-sizing: border-box; }
20
+ body {
21
+ margin: 0;
22
+ background: var(--bg);
23
+ color: var(--text);
24
+ font-size: 17px;
25
+ }
26
+ header {
27
+ border-bottom: 1px solid var(--line);
28
+ padding: 16px 20px;
29
+ }
30
+ .title-row {
31
+ align-items: center;
32
+ display: flex;
33
+ gap: 8px;
34
+ margin-bottom: 8px;
35
+ }
36
+ h1 {
37
+ font-size: 22px;
38
+ line-height: 1.2;
39
+ margin: 0;
40
+ font-weight: 650;
41
+ }
42
+ .icon-button {
43
+ align-items: center;
44
+ display: inline-flex;
45
+ height: 34px;
46
+ justify-content: center;
47
+ padding: 0;
48
+ width: 34px;
49
+ }
50
+ .icon-button svg {
51
+ height: 18px;
52
+ width: 18px;
53
+ }
54
+ .path {
55
+ color: var(--muted);
56
+ font-size: 14px;
57
+ overflow-wrap: anywhere;
58
+ }
59
+ main {
60
+ max-width: 980px;
61
+ margin: 0 auto;
62
+ padding: 20px;
63
+ }
64
+ .toolbar {
65
+ align-items: center;
66
+ display: flex;
67
+ flex-wrap: wrap;
68
+ gap: 12px;
69
+ justify-content: flex-end;
70
+ margin-bottom: 14px;
71
+ min-height: 36px;
72
+ }
73
+ .tabs {
74
+ display: flex;
75
+ gap: 8px;
76
+ margin-bottom: 14px;
77
+ overflow-x: auto;
78
+ }
79
+ .tab {
80
+ border-color: transparent;
81
+ min-width: 110px;
82
+ }
83
+ .tab[aria-selected="true"] {
84
+ background: var(--panel);
85
+ border-color: var(--line);
86
+ }
87
+ .tab-panel[hidden] {
88
+ display: none;
89
+ }
90
+ button:focus-visible,
91
+ select:focus-visible,
92
+ input:focus-visible {
93
+ outline: 2px solid var(--accent);
94
+ outline-offset: 2px;
95
+ }
96
+ .language-picker {
97
+ align-items: center;
98
+ display: inline-flex;
99
+ flex-shrink: 0;
100
+ gap: 8px;
101
+ }
102
+ .language-picker span {
103
+ color: var(--muted);
104
+ font-size: 14px;
105
+ white-space: nowrap;
106
+ }
107
+ .language-picker select {
108
+ min-width: 130px;
109
+ }
110
+ .status {
111
+ color: var(--muted);
112
+ font-size: 15px;
113
+ margin-right: auto;
114
+ }
115
+ .status.ok { color: var(--ok); }
116
+ .status.error { color: var(--danger); }
117
+ .last-updated {
118
+ color: var(--muted);
119
+ font-size: 13px;
120
+ white-space: nowrap;
121
+ }
122
+ button, select, input {
123
+ background: #11141a;
124
+ border: 1px solid var(--line);
125
+ border-radius: 6px;
126
+ color: var(--text);
127
+ font: inherit;
128
+ min-height: 38px;
129
+ }
130
+ button {
131
+ cursor: pointer;
132
+ padding: 0 14px;
133
+ }
134
+ button:disabled {
135
+ cursor: not-allowed;
136
+ opacity: 0.6;
137
+ }
138
+ section {
139
+ border-top: 1px solid var(--line);
140
+ padding: 14px 0;
141
+ }
142
+ h2 {
143
+ font-size: 15px;
144
+ line-height: 1.25;
145
+ margin: 0 0 8px;
146
+ color: var(--muted);
147
+ font-weight: 650;
148
+ }
149
+ .setting {
150
+ align-items: center;
151
+ display: grid;
152
+ gap: 12px;
153
+ grid-template-columns: minmax(220px, 1fr) minmax(120px, 240px);
154
+ min-height: 48px;
155
+ padding: 6px 0;
156
+ }
157
+ .settings-pending {
158
+ border: 1px solid var(--line);
159
+ border-radius: 6px;
160
+ margin-bottom: 14px;
161
+ padding: 10px 12px;
162
+ }
163
+ .settings-pending[hidden] {
164
+ display: none;
165
+ }
166
+ .settings-pending-header {
167
+ align-items: center;
168
+ display: flex;
169
+ flex-wrap: wrap;
170
+ gap: 10px;
171
+ justify-content: space-between;
172
+ }
173
+ .settings-pending-title {
174
+ color: var(--text);
175
+ font-size: 15px;
176
+ font-weight: 650;
177
+ }
178
+ .settings-pending-list {
179
+ color: var(--muted);
180
+ font-size: 13px;
181
+ line-height: 1.45;
182
+ margin: 8px 0 0;
183
+ padding-left: 18px;
184
+ }
185
+ .label {
186
+ font-size: 16px;
187
+ }
188
+ .value-description {
189
+ color: var(--muted);
190
+ font-size: 13px;
191
+ line-height: 1.35;
192
+ margin-left: 10px;
193
+ }
194
+ .meta {
195
+ color: var(--muted);
196
+ font-size: 13px;
197
+ margin-top: 2px;
198
+ }
199
+ .status-grid {
200
+ display: grid;
201
+ gap: 8px;
202
+ grid-template-columns: repeat(2, minmax(0, 1fr));
203
+ }
204
+ .status-item {
205
+ border-bottom: 1px solid var(--line);
206
+ display: grid;
207
+ gap: 4px;
208
+ padding: 8px 0;
209
+ }
210
+ .status-label {
211
+ color: var(--muted);
212
+ font-size: 13px;
213
+ }
214
+ .status-value {
215
+ align-items: center;
216
+ display: flex;
217
+ flex-wrap: wrap;
218
+ gap: 6px;
219
+ font-size: 15px;
220
+ overflow-wrap: anywhere;
221
+ }
222
+ .status-value.ok { color: var(--ok); }
223
+ .status-value.warn { color: var(--danger); }
224
+ .status-badge {
225
+ border: 1px solid var(--line);
226
+ border-radius: 999px;
227
+ color: var(--text);
228
+ display: inline-flex;
229
+ font-size: 12px;
230
+ font-weight: 650;
231
+ line-height: 1;
232
+ padding: 3px 7px;
233
+ white-space: nowrap;
234
+ }
235
+ .status-badge.ok {
236
+ border-color: rgba(155, 231, 186, 0.55);
237
+ color: var(--ok);
238
+ }
239
+ .status-badge.warn {
240
+ border-color: rgba(255, 154, 154, 0.55);
241
+ color: var(--danger);
242
+ }
243
+ .next-actions {
244
+ display: grid;
245
+ gap: 0;
246
+ }
247
+ .next-action-row {
248
+ align-items: center;
249
+ border-bottom: 1px solid var(--line);
250
+ display: grid;
251
+ gap: 10px;
252
+ grid-template-columns: minmax(0, 1fr) auto;
253
+ padding: 8px 0;
254
+ }
255
+ .next-action-title {
256
+ font-size: 15px;
257
+ font-weight: 650;
258
+ overflow-wrap: anywhere;
259
+ }
260
+ .next-action-meta {
261
+ color: var(--muted);
262
+ font-size: 13px;
263
+ margin-top: 2px;
264
+ overflow-wrap: anywhere;
265
+ }
266
+ .next-action-row button {
267
+ min-height: 34px;
268
+ padding: 0 10px;
269
+ }
270
+ .issue-list {
271
+ margin: 0;
272
+ padding-left: 18px;
273
+ }
274
+ .issue-list li {
275
+ margin: 4px 0;
276
+ overflow-wrap: anywhere;
277
+ }
278
+ .command-row {
279
+ align-items: start;
280
+ background: var(--row-bg);
281
+ border-bottom: 1px solid var(--line);
282
+ border-radius: 6px;
283
+ display: grid;
284
+ gap: 10px;
285
+ grid-template-columns: minmax(160px, 220px) 1fr;
286
+ margin-bottom: 6px;
287
+ padding: 10px;
288
+ }
289
+ .command-row:nth-of-type(even) {
290
+ background: var(--row-bg-alt);
291
+ }
292
+ .command-name {
293
+ font-weight: 650;
294
+ overflow-wrap: anywhere;
295
+ }
296
+ .command-state {
297
+ align-items: center;
298
+ background: var(--status-neutral-bg);
299
+ border: 1px solid var(--line);
300
+ border-radius: 999px;
301
+ color: var(--muted);
302
+ display: inline-flex;
303
+ font-size: 13px;
304
+ font-weight: 650;
305
+ line-height: 1;
306
+ margin-top: 4px;
307
+ padding: 4px 7px;
308
+ white-space: nowrap;
309
+ }
310
+ .command-state.ok {
311
+ background: var(--status-ok-bg);
312
+ border-color: rgba(155, 231, 186, 0.55);
313
+ color: var(--ok);
314
+ }
315
+ .command-state.warn {
316
+ background: var(--status-warn-bg);
317
+ border-color: rgba(255, 154, 154, 0.55);
318
+ color: var(--danger);
319
+ }
320
+ .command-description {
321
+ font-size: 15px;
322
+ overflow-wrap: anywhere;
323
+ }
324
+ .command-meta {
325
+ color: var(--muted);
326
+ display: flex;
327
+ flex-wrap: wrap;
328
+ font-size: 13px;
329
+ gap: 8px 14px;
330
+ margin-top: 6px;
331
+ }
332
+ .command-note {
333
+ color: var(--muted);
334
+ font-size: 13px;
335
+ margin-top: 6px;
336
+ overflow-wrap: anywhere;
337
+ }
338
+ .collapsible-details {
339
+ border-top: 1px solid var(--line);
340
+ padding: 10px 0;
341
+ }
342
+ .collapsible-details > summary {
343
+ color: var(--muted);
344
+ cursor: pointer;
345
+ font-size: 15px;
346
+ font-weight: 650;
347
+ overflow-wrap: anywhere;
348
+ }
349
+ .collapsible-details > summary:focus-visible {
350
+ outline: 2px solid var(--accent);
351
+ outline-offset: 2px;
352
+ }
353
+ .collapsible-details[open] > summary {
354
+ color: var(--text);
355
+ margin-bottom: 8px;
356
+ }
357
+ .verification-row {
358
+ align-items: start;
359
+ background: var(--row-bg);
360
+ border-bottom: 1px solid var(--line);
361
+ border-radius: 6px;
362
+ display: grid;
363
+ gap: 10px;
364
+ grid-template-columns: minmax(160px, 220px) 1fr auto;
365
+ margin-bottom: 6px;
366
+ padding: 10px;
367
+ }
368
+ .verification-row:nth-of-type(even) {
369
+ background: var(--row-bg-alt);
370
+ }
371
+ .verification-command {
372
+ font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
373
+ font-size: 14px;
374
+ overflow-wrap: anywhere;
375
+ }
376
+ .verification-files {
377
+ color: var(--muted);
378
+ font-size: 13px;
379
+ margin-top: 6px;
380
+ overflow-wrap: anywhere;
381
+ }
382
+ .verification-copy {
383
+ min-height: 34px;
384
+ padding: 0 10px;
385
+ }
386
+ .list-filters {
387
+ align-items: end;
388
+ display: grid;
389
+ gap: 10px;
390
+ grid-template-columns: minmax(180px, 1fr) minmax(130px, 190px);
391
+ margin: 0 0 12px;
392
+ }
393
+ .list-filters label {
394
+ display: grid;
395
+ gap: 5px;
396
+ }
397
+ .list-filters span {
398
+ color: var(--muted);
399
+ font-size: 13px;
400
+ }
401
+ .doc-controls {
402
+ display: grid;
403
+ gap: 10px;
404
+ margin-bottom: 14px;
405
+ }
406
+ .doc-filter-controls,
407
+ .doc-review-controls {
408
+ align-items: end;
409
+ display: grid;
410
+ gap: 10px;
411
+ }
412
+ .doc-filter-controls {
413
+ grid-template-columns: minmax(130px, 160px) minmax(180px, 1fr);
414
+ }
415
+ .doc-review-controls {
416
+ grid-template-columns: minmax(130px, 170px) minmax(160px, 1fr) minmax(180px, 1fr);
417
+ }
418
+ .doc-controls label,
419
+ .doc-control-group-label {
420
+ display: grid;
421
+ gap: 5px;
422
+ }
423
+ .doc-controls span,
424
+ .doc-control-group-label {
425
+ color: var(--muted);
426
+ font-size: 13px;
427
+ }
428
+ .doc-reviewer-state {
429
+ color: var(--muted);
430
+ font-size: 13px;
431
+ margin-bottom: 10px;
432
+ }
433
+ .doc-reviewer-state.warn {
434
+ color: var(--danger);
435
+ }
436
+ .doc-list {
437
+ border-top: 1px solid var(--line);
438
+ }
439
+ .doc-row {
440
+ align-items: start;
441
+ background: var(--row-bg);
442
+ border-bottom: 1px solid var(--line);
443
+ border-radius: 6px;
444
+ display: grid;
445
+ gap: 12px;
446
+ grid-template-columns: minmax(0, 1fr) minmax(90px, auto) auto;
447
+ margin-bottom: 6px;
448
+ padding: 10px;
449
+ }
450
+ .doc-row:nth-of-type(even) {
451
+ background: var(--row-bg-alt);
452
+ }
453
+ .doc-path {
454
+ font-size: 15px;
455
+ overflow-wrap: anywhere;
456
+ }
457
+ .doc-meta {
458
+ color: var(--muted);
459
+ font-size: 13px;
460
+ margin-top: 3px;
461
+ overflow-wrap: anywhere;
462
+ }
463
+ .doc-comment {
464
+ background: rgba(255, 255, 255, 0.04);
465
+ border: 1px solid var(--line);
466
+ border-radius: 6px;
467
+ color: var(--text);
468
+ font: inherit;
469
+ font-size: 13px;
470
+ line-height: 1.45;
471
+ margin: 8px 0 0;
472
+ max-height: 180px;
473
+ overflow: auto;
474
+ padding: 8px;
475
+ white-space: pre-wrap;
476
+ }
477
+ .doc-status {
478
+ align-items: center;
479
+ background: var(--status-neutral-bg);
480
+ border: 1px solid var(--line);
481
+ border-radius: 999px;
482
+ color: var(--muted);
483
+ display: inline-flex;
484
+ font-size: 13px;
485
+ font-weight: 650;
486
+ line-height: 1;
487
+ padding: 4px 7px;
488
+ white-space: nowrap;
489
+ }
490
+ .doc-status.approved {
491
+ background: var(--status-ok-bg);
492
+ border-color: rgba(155, 231, 186, 0.55);
493
+ color: var(--ok);
494
+ }
495
+ .doc-status.needs_human {
496
+ background: var(--status-warn-bg);
497
+ border-color: rgba(255, 154, 154, 0.55);
498
+ color: var(--danger);
499
+ }
500
+ .doc-actions {
501
+ display: flex;
502
+ flex-wrap: wrap;
503
+ gap: 8px;
504
+ justify-content: flex-end;
505
+ }
506
+ .doc-actions button {
507
+ min-height: 34px;
508
+ padding: 0 10px;
509
+ }
510
+ .empty {
511
+ color: var(--muted);
512
+ padding: 14px 0;
513
+ }
514
+ select, input[type="number"], input[type="text"] {
515
+ padding: 0 12px;
516
+ width: 100%;
517
+ }
518
+ select {
519
+ appearance: none;
520
+ background-image:
521
+ linear-gradient(45deg, transparent 50%, currentColor 50%),
522
+ linear-gradient(135deg, currentColor 50%, transparent 50%);
523
+ background-position:
524
+ calc(100% - 22px) 50%,
525
+ calc(100% - 16px) 50%;
526
+ background-repeat: no-repeat;
527
+ background-size: 6px 6px, 6px 6px;
528
+ padding-right: 44px;
529
+ }
530
+ select::-ms-expand {
531
+ display: none;
532
+ }
533
+ .setting-control {
534
+ width: 100%;
535
+ }
536
+ .locale-tag-control {
537
+ display: grid;
538
+ gap: 8px;
539
+ width: 100%;
540
+ }
541
+ .locale-tag-control input[hidden] {
542
+ display: none;
543
+ }
544
+ input[type="checkbox"] {
545
+ height: 22px;
546
+ justify-self: end;
547
+ min-height: 22px;
548
+ width: 22px;
549
+ }
550
+ @media (max-width: 640px) {
551
+ main { padding: 14px; }
552
+ .setting {
553
+ grid-template-columns: 1fr;
554
+ gap: 6px;
555
+ }
556
+ input[type="checkbox"] {
557
+ justify-self: start;
558
+ }
559
+ .doc-controls,
560
+ .doc-filter-controls,
561
+ .doc-review-controls,
562
+ .list-filters,
563
+ .doc-row,
564
+ .verification-row,
565
+ .status-grid {
566
+ grid-template-columns: 1fr;
567
+ }
568
+ .doc-actions {
569
+ justify-content: flex-start;
570
+ }
571
+ }`;
572
+ }
@@ -0,0 +1,134 @@
1
+ import { renderDashboardClientScript } from './client-script.js';
2
+ import { createDashboardLocaleBootstrap } from './locale-bootstrap.js';
3
+ import { renderDashboardStyles } from './styles.js';
4
+ function escapeHtml(value) {
5
+ return value
6
+ .replace(/&/g, '&')
7
+ .replace(/</g, '&lt;')
8
+ .replace(/>/g, '&gt;')
9
+ .replace(/"/g, '&quot;')
10
+ .replace(/'/g, '&#39;');
11
+ }
12
+ export function renderDashboardHtml(snapshot, token, statusSnapshot, docReviewSnapshot) {
13
+ const root = escapeHtml(snapshot.projectRoot);
14
+ const preferencesPath = escapeHtml(snapshot.preferencesPath);
15
+ const serializedSnapshot = JSON.stringify(snapshot);
16
+ const serializedStatusSnapshot = JSON.stringify(statusSnapshot);
17
+ const serializedDocReviewSnapshot = JSON.stringify(docReviewSnapshot);
18
+ const serializedToken = JSON.stringify(token);
19
+ const { serializedLocaleBundle, serializedAvailableLocales } = createDashboardLocaleBootstrap();
20
+ return `<!doctype html>
21
+ <html lang="en">
22
+ <head>
23
+ <meta charset="utf-8">
24
+ <meta name="viewport" content="width=device-width, initial-scale=1">
25
+ <title>mustflow dashboard</title>
26
+ <style>
27
+ ${renderDashboardStyles()}
28
+ </style>
29
+ </head>
30
+ <body>
31
+ <header>
32
+ <div class="title-row">
33
+ <h1 id="dashboard-title">mustflow dashboard</h1>
34
+ <button id="open-mustflow" class="icon-button" type="button" aria-label="Open .mustflow folder" title="Open .mustflow folder">
35
+ <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
36
+ <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.2a2 2 0 0 1-1.6-.8L10 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2Z"></path>
37
+ </svg>
38
+ </button>
39
+ </div>
40
+ <div class="path">${root}</div>
41
+ <div class="path">${preferencesPath}</div>
42
+ </header>
43
+ <main>
44
+ <nav class="tabs" role="tablist" aria-label="Dashboard sections">
45
+ <button id="tab-status" class="tab" type="button" role="tab" data-tab="status" aria-controls="panel-status" aria-selected="true" tabindex="0">Status</button>
46
+ <button id="tab-verification" class="tab" type="button" role="tab" data-tab="verification" aria-controls="panel-verification" aria-selected="false" tabindex="-1">Verification</button>
47
+ <button id="tab-commands" class="tab" type="button" role="tab" data-tab="commands" aria-controls="panel-commands" aria-selected="false" tabindex="-1">Commands</button>
48
+ <button id="tab-release" class="tab" type="button" role="tab" data-tab="release" aria-controls="panel-release" aria-selected="false" tabindex="-1">Release</button>
49
+ <button id="tab-update" class="tab" type="button" role="tab" data-tab="update" aria-controls="panel-update" aria-selected="false" tabindex="-1">Update</button>
50
+ <button id="tab-runs" class="tab" type="button" role="tab" data-tab="runs" aria-controls="panel-runs" aria-selected="false" tabindex="-1">Runs</button>
51
+ <button id="tab-skills" class="tab" type="button" role="tab" data-tab="skills" aria-controls="panel-skills" aria-selected="false" tabindex="-1">Skills</button>
52
+ <button id="tab-settings" class="tab" type="button" role="tab" data-tab="settings" aria-controls="panel-settings" aria-selected="false" tabindex="-1">Settings</button>
53
+ <button id="tab-documents" class="tab" type="button" role="tab" data-tab="documents" aria-controls="panel-documents" aria-selected="false" tabindex="-1">Documents</button>
54
+ </nav>
55
+ <div class="toolbar">
56
+ <div id="status" class="status" role="status" aria-live="polite">No changes</div>
57
+ <div id="last-updated" class="last-updated" aria-live="polite"></div>
58
+ <label class="language-picker" for="dashboard-language">
59
+ <span id="dashboard-language-label">Language</span>
60
+ <select id="dashboard-language" name="dashboard-language"></select>
61
+ </label>
62
+ <button id="reload" type="button">Reload</button>
63
+ <button id="save" type="button" disabled>Save</button>
64
+ </div>
65
+ <div id="panel-status" class="tab-panel" role="tabpanel" aria-labelledby="tab-status">
66
+ <div id="dashboard-status"></div>
67
+ </div>
68
+ <div id="panel-verification" class="tab-panel" role="tabpanel" aria-labelledby="tab-verification" hidden>
69
+ <div id="dashboard-verification"></div>
70
+ </div>
71
+ <div id="panel-commands" class="tab-panel" role="tabpanel" aria-labelledby="tab-commands" hidden>
72
+ <div id="dashboard-commands"></div>
73
+ </div>
74
+ <div id="panel-release" class="tab-panel" role="tabpanel" aria-labelledby="tab-release" hidden>
75
+ <div id="dashboard-release"></div>
76
+ </div>
77
+ <div id="panel-update" class="tab-panel" role="tabpanel" aria-labelledby="tab-update" hidden>
78
+ <div id="dashboard-update"></div>
79
+ </div>
80
+ <div id="panel-runs" class="tab-panel" role="tabpanel" aria-labelledby="tab-runs" hidden>
81
+ <div id="dashboard-runs"></div>
82
+ </div>
83
+ <div id="panel-skills" class="tab-panel" role="tabpanel" aria-labelledby="tab-skills" hidden>
84
+ <div id="dashboard-skills"></div>
85
+ </div>
86
+ <div id="panel-settings" class="tab-panel" role="tabpanel" aria-labelledby="tab-settings" hidden>
87
+ <div id="settings-pending-summary" class="settings-pending" aria-live="polite" hidden></div>
88
+ <div id="settings"></div>
89
+ </div>
90
+ <div id="panel-documents" class="tab-panel" role="tabpanel" aria-labelledby="tab-documents" hidden>
91
+ <div class="doc-controls">
92
+ <div class="doc-filter-controls">
93
+ <label for="doc-status-filter">
94
+ <span id="doc-status-filter-label">Status</span>
95
+ <select id="doc-status-filter"></select>
96
+ </label>
97
+ <label for="doc-path-filter">
98
+ <span id="doc-path-filter-label">File name</span>
99
+ <input id="doc-path-filter" type="text" autocomplete="off" spellcheck="false">
100
+ </label>
101
+ </div>
102
+ <div class="doc-control-group-label" id="doc-review-fields-label">Review record</div>
103
+ <div class="doc-review-controls">
104
+ <label for="doc-reviewer-kind">
105
+ <span id="doc-reviewer-kind-label">Reviewer kind</span>
106
+ <select id="doc-reviewer-kind"></select>
107
+ </label>
108
+ <label for="doc-reviewer-id">
109
+ <span id="doc-reviewer-id-label">Reviewer ID</span>
110
+ <input id="doc-reviewer-id" type="text" autocomplete="off" spellcheck="false">
111
+ </label>
112
+ <label for="doc-review-summary">
113
+ <span id="doc-review-summary-label">Summary</span>
114
+ <input id="doc-review-summary" type="text" autocomplete="off">
115
+ </label>
116
+ </div>
117
+ </div>
118
+ <div id="doc-reviewer-state" class="doc-reviewer-state" aria-live="polite"></div>
119
+ <div id="docs-review-list" class="doc-list"></div>
120
+ </div>
121
+ </main>
122
+ <script>
123
+ ${renderDashboardClientScript({
124
+ serializedSnapshot,
125
+ serializedToken,
126
+ serializedLocaleBundle,
127
+ serializedAvailableLocales,
128
+ serializedStatusSnapshot,
129
+ serializedDocReviewSnapshot,
130
+ })}
131
+ </script>
132
+ </body>
133
+ </html>`;
134
+ }
@@ -0,0 +1 @@
1
+ export {};