@markbrutx/promptbook-viewer 0.3.0 → 0.4.1

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.
@@ -1,30 +1,51 @@
1
1
  :root {
2
- --bg: #fff;
3
- --panel: #f6f8fa;
4
- --border: #e1e4e8;
5
- --text: #1f2328;
6
- --muted: #6e7781;
7
- --accent: #4f46e5;
8
- --warn: #b35900;
9
- font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
10
- font-size: 14px;
11
- color: var(--text);
2
+ --bg: #0a0b0e;
3
+ --panel: #111317;
4
+ --panel-2: #15181d;
5
+ --border: #22262e;
6
+ --border-strong: #3a3f49;
7
+ --text: #eceef1;
8
+ --muted: #8b919c;
9
+ --subtle: #5a5f69;
10
+ --accent: #b8ff66;
11
+ --accent-soft: rgba(184, 255, 102, 0.18);
12
+ --warn: #ffb347;
13
+ --danger: #ff6e8a;
14
+ }
15
+
16
+ .layout * {
17
+ box-sizing: border-box;
12
18
  }
13
19
 
14
- * {
15
- box-sizing: border-box;
20
+ .layout {
21
+ display: grid;
22
+ grid-template-columns: 260px minmax(0, 1fr) 380px;
23
+ height: 100%;
24
+ min-height: 600px;
25
+ background: var(--bg);
26
+ color: var(--text);
27
+ font-family: var(--font-sans-next), ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
28
+ font-size: 14px;
29
+ /* Match the rest of the dark site so form controls render with the right
30
+ chrome and pastel fragment tints stay readable. */
31
+ color-scheme: dark;
16
32
  }
17
33
 
18
- body {
34
+ /* When the viewer is the only thing on the page (CLI `promptbook view`), let it
35
+ fill the viewport. The site's demo island sizes the host explicitly. */
36
+ html:has(> body > #root > .layout) body {
19
37
  margin: 0;
20
38
  background: var(--bg);
21
39
  }
22
-
23
- .layout {
24
- display: grid;
25
- grid-template-columns: 260px minmax(0, 1fr) 380px;
40
+ html:has(> body > #root > .layout) {
41
+ height: 100%;
42
+ }
43
+ html:has(> body > #root > .layout) body {
26
44
  height: 100vh;
27
45
  }
46
+ #root:has(> .layout) {
47
+ height: 100%;
48
+ }
28
49
 
29
50
  /* Sidebar */
30
51
  .sidebar {
@@ -102,12 +123,16 @@ body {
102
123
  }
103
124
 
104
125
  .tree-item:hover {
105
- background: #eaeef2;
126
+ background: var(--panel-2);
127
+ color: var(--text);
106
128
  }
107
129
 
108
130
  .tree-item.active {
109
- background: var(--accent);
110
- color: #fff;
131
+ background: var(--accent-soft);
132
+ color: var(--accent);
133
+ border-left: 2px solid var(--accent);
134
+ border-radius: 0 4px 4px 0;
135
+ padding-left: 4px;
111
136
  }
112
137
 
113
138
  .link {
@@ -175,6 +200,11 @@ body {
175
200
  padding: 16px 12px 12px;
176
201
  border-radius: 6px;
177
202
  border: 1px solid var(--border);
203
+ /* Pin the colour so the segment text stays readable even when the viewer is
204
+ embedded in a page whose root sets `color` to something else (Fumadocs +
205
+ dark-mode-aware tokens used to leak in here, painting text near-invisible
206
+ on the pastel tints). */
207
+ color: var(--text);
178
208
  white-space: pre-wrap;
179
209
  word-break: break-word;
180
210
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
@@ -187,10 +217,15 @@ body {
187
217
  top: 0;
188
218
  right: 0;
189
219
  font-size: 10px;
190
- padding: 1px 6px;
191
- background: rgba(0, 0, 0, 0.06);
220
+ padding: 2px 8px;
221
+ background: rgba(0, 0, 0, 0.32);
222
+ border: 1px solid var(--border);
223
+ border-top: none;
224
+ border-right: none;
192
225
  border-bottom-left-radius: 6px;
193
- font-family: system-ui, sans-serif;
226
+ font-family: var(--font-mono-next), ui-monospace, "SF Mono", Menlo, monospace;
227
+ text-transform: uppercase;
228
+ letter-spacing: 0.08em;
194
229
  color: var(--muted);
195
230
  }
196
231
 
@@ -224,11 +259,19 @@ body {
224
259
  select,
225
260
  input {
226
261
  width: 100%;
227
- padding: 4px 6px;
262
+ padding: 5px 8px;
228
263
  border: 1px solid var(--border);
229
- border-radius: 5px;
264
+ border-radius: 4px;
230
265
  font: inherit;
231
- background: #fff;
266
+ background: var(--panel-2);
267
+ color: var(--text);
268
+ }
269
+
270
+ select:focus,
271
+ input:focus {
272
+ outline: none;
273
+ border-color: var(--accent);
274
+ box-shadow: 0 0 0 2px var(--accent-soft);
232
275
  }
233
276
 
234
277
  .book-switcher select {
@@ -260,10 +303,16 @@ input {
260
303
 
261
304
  .control-add button {
262
305
  border: 1px solid var(--border);
263
- border-radius: 5px;
264
- background: #fff;
306
+ border-radius: 4px;
307
+ background: var(--panel-2);
308
+ color: var(--text);
265
309
  cursor: pointer;
266
- padding: 0 10px;
310
+ padding: 0 12px;
311
+ }
312
+
313
+ .control-add button:hover {
314
+ border-color: var(--accent);
315
+ color: var(--accent);
267
316
  }
268
317
 
269
318
  /* Explain + lint */
@@ -277,32 +326,151 @@ input {
277
326
  }
278
327
 
279
328
  .rules li {
280
- padding: 4px 0;
329
+ display: grid;
330
+ grid-template-columns: 18px 1fr;
331
+ gap: 4px 6px;
332
+ padding: 6px 0;
281
333
  border-bottom: 1px solid var(--border);
282
334
  font-size: 12px;
335
+ line-height: 1.4;
283
336
  }
284
337
 
285
- .rules li.skipped {
286
- color: var(--muted);
338
+ .rules li:last-child {
339
+ border-bottom: none;
287
340
  }
288
341
 
289
342
  .rule-mark {
290
- margin-right: 6px;
343
+ font-weight: 700;
344
+ text-align: center;
345
+ }
346
+
347
+ .rule-fired .rule-mark {
348
+ color: var(--accent);
349
+ }
350
+
351
+ .rule-skipped {
352
+ color: var(--muted);
353
+ }
354
+
355
+ .rule-skipped .rule-mark {
356
+ opacity: 0.5;
357
+ }
358
+
359
+ .rule-body {
360
+ min-width: 0;
361
+ }
362
+
363
+ .rule-head {
364
+ display: flex;
365
+ flex-wrap: wrap;
366
+ gap: 6px;
367
+ align-items: baseline;
291
368
  }
292
369
 
293
370
  .rule-action {
294
371
  font-weight: 600;
295
- margin-right: 6px;
372
+ font-family: ui-monospace, monospace;
373
+ color: var(--text);
374
+ }
375
+
376
+ .rule-skipped .rule-action {
377
+ color: var(--muted);
378
+ }
379
+
380
+ .rule-when {
381
+ font-family: ui-monospace, monospace;
382
+ color: var(--muted);
383
+ font-size: 11px;
296
384
  }
297
385
 
298
386
  .rule-effect {
299
387
  font-family: ui-monospace, monospace;
300
- margin-top: 2px;
388
+ margin: 4px 0 0;
389
+ color: var(--text);
301
390
  }
302
391
 
303
392
  .rule-reason {
304
393
  color: var(--muted);
305
- margin-top: 2px;
394
+ margin: 4px 0 0;
395
+ font-style: italic;
396
+ font-size: 11px;
397
+ }
398
+
399
+ .skipped-block {
400
+ margin-top: 10px;
401
+ border-top: 1px dashed var(--border);
402
+ padding-top: 8px;
403
+ }
404
+
405
+ .skipped-summary {
406
+ cursor: pointer;
407
+ font-size: 11px;
408
+ color: var(--muted);
409
+ text-transform: uppercase;
410
+ letter-spacing: 0.06em;
411
+ list-style: none;
412
+ padding: 2px 0;
413
+ }
414
+
415
+ .skipped-summary::-webkit-details-marker {
416
+ display: none;
417
+ }
418
+
419
+ .skipped-summary::before {
420
+ content: "▸";
421
+ display: inline-block;
422
+ margin-right: 6px;
423
+ transition: transform 120ms ease;
424
+ }
425
+
426
+ .skipped-block[open] .skipped-summary::before {
427
+ transform: rotate(90deg);
428
+ }
429
+
430
+ .effects {
431
+ display: grid;
432
+ grid-template-columns: 80px 1fr;
433
+ gap: 4px 8px;
434
+ margin: 8px 0;
435
+ font-size: 12px;
436
+ }
437
+
438
+ .effects dt {
439
+ font-family: ui-monospace, monospace;
440
+ color: var(--muted);
441
+ text-transform: uppercase;
442
+ font-size: 10px;
443
+ letter-spacing: 0.06em;
444
+ padding-top: 2px;
445
+ }
446
+
447
+ .effects dd {
448
+ margin: 0;
449
+ font-family: ui-monospace, monospace;
450
+ word-break: break-word;
451
+ }
452
+
453
+ .notice {
454
+ margin: 8px 0 0;
455
+ font-size: 12px;
456
+ color: var(--text);
457
+ background: rgba(255, 179, 71, 0.08);
458
+ border: 1px solid rgba(255, 179, 71, 0.35);
459
+ border-radius: 5px;
460
+ padding: 8px 10px;
461
+ }
462
+
463
+ .notice strong {
464
+ display: block;
465
+ color: var(--warn);
466
+ font-size: 11px;
467
+ text-transform: uppercase;
468
+ letter-spacing: 0.06em;
469
+ margin-bottom: 2px;
470
+ }
471
+
472
+ .small {
473
+ font-size: 11px;
306
474
  }
307
475
 
308
476
  .order {
@@ -325,18 +493,20 @@ input {
325
493
  text-transform: uppercase;
326
494
  font-size: 10px;
327
495
  font-weight: 700;
328
- padding: 1px 5px;
329
- border-radius: 4px;
330
- background: #eaeef2;
496
+ letter-spacing: 0.08em;
497
+ padding: 2px 6px;
498
+ border-radius: 3px;
499
+ background: var(--panel-2);
500
+ color: var(--muted);
331
501
  }
332
502
 
333
503
  .finding.error .finding-sev {
334
- background: #ffd7d5;
335
- color: #a40e26;
504
+ background: rgba(255, 110, 138, 0.14);
505
+ color: var(--danger);
336
506
  }
337
507
 
338
508
  .finding.warning .finding-sev {
339
- background: #fff1c2;
509
+ background: rgba(255, 179, 71, 0.14);
340
510
  color: var(--warn);
341
511
  }
342
512
 
@@ -353,7 +523,7 @@ input {
353
523
  border: 1px solid var(--border);
354
524
  border-radius: 6px;
355
525
  overflow-x: auto;
356
- background: #fff;
526
+ background: var(--panel-2);
357
527
  }
358
528
 
359
529
  .diff-row {
@@ -362,11 +532,13 @@ input {
362
532
  }
363
533
 
364
534
  .diff-row.add {
365
- background: #e6ffec;
535
+ background: rgba(184, 255, 102, 0.1);
536
+ color: var(--accent);
366
537
  }
367
538
 
368
539
  .diff-row.remove {
369
- background: #ffebe9;
540
+ background: rgba(255, 110, 138, 0.12);
541
+ color: var(--danger);
370
542
  }
371
543
 
372
544
  .diff-mark {
@@ -377,21 +549,23 @@ input {
377
549
 
378
550
  /* Annotations */
379
551
  .annot-mark {
380
- background: #fff3b0;
552
+ background: rgba(255, 179, 71, 0.18);
381
553
  border-bottom: 2px solid var(--warn);
382
554
  border-radius: 2px;
383
555
  padding: 0 1px;
556
+ color: var(--text);
384
557
  }
385
558
 
386
559
  .annot-popover {
387
560
  position: fixed;
388
561
  z-index: 20;
389
562
  width: 280px;
390
- padding: 10px;
391
- background: #fff;
392
- border: 1px solid var(--border);
393
- border-radius: 8px;
394
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
563
+ padding: 12px;
564
+ background: var(--panel);
565
+ border: 1px solid var(--border-strong);
566
+ border-radius: 6px;
567
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.6);
568
+ color: var(--text);
395
569
  }
396
570
 
397
571
  .annot-popover textarea {
@@ -409,12 +583,18 @@ input {
409
583
  }
410
584
 
411
585
  .annot-actions button[type="button"]:last-child {
412
- border: 1px solid var(--border);
413
- border-radius: 5px;
586
+ border: 1px solid var(--accent);
587
+ border-radius: 4px;
414
588
  background: var(--accent);
415
- color: #fff;
589
+ color: var(--bg);
416
590
  padding: 4px 12px;
417
591
  cursor: pointer;
592
+ font-weight: 600;
593
+ }
594
+
595
+ .annot-actions button[type="button"]:last-child:hover {
596
+ background: transparent;
597
+ color: var(--accent);
418
598
  }
419
599
 
420
600
  .annot-actions button[disabled] {
@@ -457,19 +637,23 @@ input {
457
637
 
458
638
  /* Shared */
459
639
  .badge {
460
- font-size: 12px;
640
+ font-size: 11px;
461
641
  padding: 2px 8px;
462
642
  border-radius: 999px;
463
- background: #eaeef2;
643
+ background: var(--panel-2);
644
+ color: var(--muted);
645
+ border: 1px solid var(--border);
464
646
  white-space: nowrap;
465
647
  }
466
648
 
467
649
  .badge-code {
468
650
  font-size: 10px;
469
651
  text-transform: uppercase;
470
- letter-spacing: 0.06em;
471
- background: #2b2b40;
472
- color: #fff;
652
+ letter-spacing: 0.08em;
653
+ background: var(--accent);
654
+ color: var(--bg);
655
+ border-color: var(--accent);
656
+ font-weight: 700;
473
657
  }
474
658
 
475
659
  /* Code-prompt canvas */
@@ -483,17 +667,25 @@ input {
483
667
  .code-tab {
484
668
  font: inherit;
485
669
  font-size: 12px;
486
- padding: 3px 10px;
670
+ padding: 4px 12px;
487
671
  border-radius: 999px;
488
672
  border: 1px solid var(--border);
489
673
  background: var(--panel);
490
- color: var(--text);
674
+ color: var(--muted);
491
675
  cursor: pointer;
676
+ font-family: var(--font-mono-next), ui-monospace, monospace;
677
+ }
678
+
679
+ .code-tab:hover {
680
+ color: var(--text);
681
+ border-color: var(--border-strong);
492
682
  }
493
683
 
494
684
  .code-tab.active {
495
685
  background: var(--accent);
496
686
  border-color: var(--accent);
687
+ color: var(--bg);
688
+ font-weight: 600;
497
689
  }
498
690
 
499
691
  .code-diff {
package/src/web/types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Single import surface for the web app: core scalar/trace types plus the
2
2
  // wire DTOs. Everything here is type-only and erased from the bundle.
3
- export type { Context, ContextValue, Trace, When } from "@markbrutx/promptbook-core";
3
+ export type { Context, ContextValue, RuleTrace, Trace, When } from "@markbrutx/promptbook-core";
4
4
  export type {
5
5
  AnnotateRequest,
6
6
  Annotation,
@@ -1 +0,0 @@
1
- :root{--bg: #fff;--panel: #f6f8fa;--border: #e1e4e8;--text: #1f2328;--muted: #6e7781;--accent: #4f46e5;--warn: #b35900;font-family:system-ui,-apple-system,Segoe UI,sans-serif;font-size:14px;color:var(--text)}*{box-sizing:border-box}body{margin:0;background:var(--bg)}.layout{display:grid;grid-template-columns:260px minmax(0,1fr) 380px;height:100vh}.sidebar{border-right:1px solid var(--border);overflow-y:auto;padding:12px;background:var(--panel)}.sidebar-brand{display:flex;flex-direction:column;gap:10px;padding:4px 4px 12px;border-bottom:1px solid var(--border);margin-bottom:4px}.sidebar-logo{width:168px;max-width:80%;height:auto;display:block;margin:8px auto 4px}.book-switcher{display:flex;align-items:center;gap:6px}.book-switcher-label{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted)}.sidebar-title{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:16px 0 6px}.tree{list-style:none;margin:0;padding-left:12px}.tree-folder,.tree-composition{cursor:pointer;font-weight:600;padding:2px 0}.tree-item,.link{display:inline-flex;align-items:center;gap:6px;width:100%;text-align:left;background:none;border:none;padding:3px 6px;border-radius:5px;color:var(--text);cursor:pointer;font:inherit}.tree-item:hover{background:#eaeef2}.tree-item.active{background:var(--accent);color:#fff}.link{width:auto;color:var(--accent);padding:0;text-decoration:underline}.swatch{width:10px;height:10px;border-radius:2px;flex:none}.canvas{overflow-y:auto;padding:20px 24px}.canvas-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:12px}.canvas-title{font-size:18px;margin:0;display:flex;align-items:center;gap:8px}.legend{list-style:none;display:flex;flex-wrap:wrap;gap:10px;padding:0;margin:0 0 14px;font-size:12px;color:var(--muted)}.legend li{display:inline-flex;align-items:center;gap:5px}.prompt{display:flex;flex-direction:column;gap:14px}.segment{position:relative;margin:0;padding:16px 12px 12px;border-radius:6px;border:1px solid var(--border);white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SF Mono,Menlo,monospace;font-size:13px;line-height:1.5}.segment-tag{position:absolute;top:0;right:0;font-size:10px;padding:1px 6px;background:#0000000f;border-bottom-left-radius:6px;font-family:system-ui,sans-serif;color:var(--muted)}.rail{border-left:1px solid var(--border);overflow-y:auto;padding:16px;background:var(--panel)}.rail section,.addons section{margin-bottom:18px}.rail h3,.addons h3{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:0 0 8px}.rail h4{margin:12px 0 4px;font-size:12px}select,input{width:100%;padding:4px 6px;border:1px solid var(--border);border-radius:5px;font:inherit;background:#fff}.book-switcher select{flex:1;width:auto}.control-row{display:grid;grid-template-columns:90px 1fr;align-items:center;gap:8px;margin-bottom:6px}.control-key{font-family:ui-monospace,monospace;font-size:12px;color:var(--muted)}.control-add{display:grid;grid-template-columns:1fr auto;gap:6px;margin-top:6px}.control-add button{border:1px solid var(--border);border-radius:5px;background:#fff;cursor:pointer;padding:0 10px}.rules,.findings,.warnings,.used-list{list-style:none;margin:0;padding:0}.rules li{padding:4px 0;border-bottom:1px solid var(--border);font-size:12px}.rules li.skipped{color:var(--muted)}.rule-mark{margin-right:6px}.rule-action{font-weight:600;margin-right:6px}.rule-effect{font-family:ui-monospace,monospace;margin-top:2px}.rule-reason{color:var(--muted);margin-top:2px}.order{font-family:ui-monospace,monospace;font-size:12px;word-break:break-word}.finding{display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;padding:5px 0;border-bottom:1px solid var(--border);font-size:12px}.finding-sev{text-transform:uppercase;font-size:10px;font-weight:700;padding:1px 5px;border-radius:4px;background:#eaeef2}.finding.error .finding-sev{background:#ffd7d5;color:#a40e26}.finding.warning .finding-sev{background:#fff1c2;color:var(--warn)}.finding-rule{font-family:ui-monospace,monospace;color:var(--muted)}.diff-body{margin:8px 0 0;font-family:ui-monospace,monospace;font-size:12px;border:1px solid var(--border);border-radius:6px;overflow-x:auto;background:#fff}.diff-row{padding:0 8px;white-space:pre-wrap}.diff-row.add{background:#e6ffec}.diff-row.remove{background:#ffebe9}.diff-mark{display:inline-block;width:12px;color:var(--muted)}.annot-mark{background:#fff3b0;border-bottom:2px solid var(--warn);border-radius:2px;padding:0 1px}.annot-popover{position:fixed;z-index:20;width:280px;padding:10px;background:#fff;border:1px solid var(--border);border-radius:8px;box-shadow:0 8px 24px #00000029}.annot-popover textarea{width:100%;min-height:64px;resize:vertical;margin:6px 0}.annot-actions{display:flex;justify-content:flex-end;gap:10px;align-items:center}.annot-actions button[type=button]:last-child{border:1px solid var(--border);border-radius:5px;background:var(--accent);color:#fff;padding:4px 12px;cursor:pointer}.annot-actions button[disabled]{opacity:.5;cursor:default}.annot-quote{margin:0;font-style:italic;color:var(--muted);font-size:12px;word-break:break-word}.annot-list{list-style:none;margin:0;padding:0}.annot-list li{padding:8px 0;border-bottom:1px solid var(--border)}.annot-comment{margin:4px 0;font-size:13px;word-break:break-word}.annot-meta{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:12px}.badge{font-size:12px;padding:2px 8px;border-radius:999px;background:#eaeef2;white-space:nowrap}.badge-code{font-size:10px;text-transform:uppercase;letter-spacing:.06em;background:#2b2b40;color:#fff}.code-tabs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}.code-tab{font:inherit;font-size:12px;padding:3px 10px;border-radius:999px;border:1px solid var(--border);background:var(--panel);color:var(--text);cursor:pointer}.code-tab.active{background:var(--accent);border-color:var(--accent)}.code-diff{margin-top:18px}.tokens{font-size:20px;font-weight:600;margin:0}.muted{color:var(--muted)}.warn{color:var(--warn)}.used-list li{padding:3px 0}