@grainulation/barn 1.0.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 (50) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +21 -0
  3. package/README.md +87 -0
  4. package/bin/barn.js +98 -0
  5. package/lib/index.js +93 -0
  6. package/lib/server.js +368 -0
  7. package/package.json +52 -0
  8. package/public/grainulation-tokens.css +321 -0
  9. package/public/index.html +907 -0
  10. package/templates/README.md +48 -0
  11. package/templates/adr.html +223 -0
  12. package/templates/adr.json +29 -0
  13. package/templates/brief.html +297 -0
  14. package/templates/brief.json +26 -0
  15. package/templates/certificate.html +247 -0
  16. package/templates/certificate.json +23 -0
  17. package/templates/changelog.html +239 -0
  18. package/templates/changelog.json +19 -0
  19. package/templates/ci-workflow.yml +52 -0
  20. package/templates/comparison.html +248 -0
  21. package/templates/comparison.json +21 -0
  22. package/templates/conflict-map.html +240 -0
  23. package/templates/conflict-map.json +19 -0
  24. package/templates/dashboard.html +515 -0
  25. package/templates/dashboard.json +22 -0
  26. package/templates/email-digest.html +178 -0
  27. package/templates/email-digest.json +18 -0
  28. package/templates/evidence-matrix.html +232 -0
  29. package/templates/evidence-matrix.json +21 -0
  30. package/templates/explainer.html +342 -0
  31. package/templates/explainer.json +23 -0
  32. package/templates/handoff.html +343 -0
  33. package/templates/handoff.json +24 -0
  34. package/templates/one-pager.html +248 -0
  35. package/templates/one-pager.json +22 -0
  36. package/templates/postmortem.html +303 -0
  37. package/templates/postmortem.json +20 -0
  38. package/templates/rfc.html +199 -0
  39. package/templates/rfc.json +32 -0
  40. package/templates/risk-register.html +231 -0
  41. package/templates/risk-register.json +22 -0
  42. package/templates/slide-deck.html +239 -0
  43. package/templates/slide-deck.json +23 -0
  44. package/templates/template.schema.json +25 -0
  45. package/templates/wiki-page.html +222 -0
  46. package/templates/wiki-page.json +23 -0
  47. package/tools/README.md +31 -0
  48. package/tools/build-pdf.js +43 -0
  49. package/tools/detect-sprints.js +292 -0
  50. package/tools/generate-manifest.js +237 -0
@@ -0,0 +1,515 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Dashboard — {{SPRINT_QUESTION}}</title>
7
+ <style>
8
+ /* barn/templates/dashboard.html — sprint dashboard template
9
+ System font stack, no external dependencies, fully self-contained. */
10
+
11
+ :root {
12
+ --bg-dark: #0f172a;
13
+ --bg-card: #1e293b;
14
+ --bg-card-alt: #1a2332;
15
+ --accent: #3b82f6;
16
+ --accent-light: #60a5fa;
17
+ --green: #22c55e;
18
+ --green-dim: rgba(34,197,94,0.15);
19
+ --orange: #f59e0b;
20
+ --orange-dim: rgba(245,158,11,0.15);
21
+ --red: #e11d48;
22
+ --red-dim: rgba(225,29,72,0.15);
23
+ --purple: #a78bfa;
24
+ --text: #f1f5f9;
25
+ --text-muted: #94a3b8;
26
+ --text-dim: #64748b;
27
+ --border: rgba(255,255,255,0.06);
28
+ }
29
+
30
+ * { margin: 0; padding: 0; box-sizing: border-box; }
31
+
32
+ body {
33
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
34
+ background: var(--bg-dark);
35
+ color: var(--text);
36
+ font-size: 10pt;
37
+ line-height: 1.5;
38
+ -webkit-font-smoothing: antialiased;
39
+ padding: 40px;
40
+ min-height: 100vh;
41
+ }
42
+
43
+ .dashboard-header {
44
+ margin-bottom: 32px;
45
+ padding-bottom: 24px;
46
+ border-bottom: 1px solid var(--border);
47
+ }
48
+
49
+ .dashboard-header h1 {
50
+ font-size: 24pt;
51
+ font-weight: 800;
52
+ letter-spacing: -0.02em;
53
+ margin-bottom: 8px;
54
+ background: linear-gradient(135deg, #fff 0%, #94a3b8 100%);
55
+ -webkit-background-clip: text;
56
+ -webkit-text-fill-color: transparent;
57
+ }
58
+
59
+ .dashboard-header .meta {
60
+ display: flex;
61
+ gap: 24px;
62
+ color: var(--text-muted);
63
+ font-size: 10pt;
64
+ }
65
+
66
+ .dashboard-header .meta .status {
67
+ font-weight: 700;
68
+ padding: 2px 10px;
69
+ border-radius: 4px;
70
+ }
71
+
72
+ .status.ready { color: var(--green); background: var(--green-dim); }
73
+ .status.blocked { color: var(--red); background: var(--red-dim); }
74
+
75
+ .grid {
76
+ display: grid;
77
+ grid-template-columns: 1fr 1fr;
78
+ gap: 24px;
79
+ margin-bottom: 24px;
80
+ }
81
+
82
+ .grid.three { grid-template-columns: 1fr 1fr 1fr; }
83
+ .grid.full { grid-template-columns: 1fr; }
84
+
85
+ .panel {
86
+ background: var(--bg-card);
87
+ border-radius: 12px;
88
+ padding: 24px;
89
+ border: 1px solid var(--border);
90
+ }
91
+
92
+ .panel-title {
93
+ font-size: 9pt;
94
+ font-weight: 700;
95
+ text-transform: uppercase;
96
+ letter-spacing: 0.1em;
97
+ color: var(--text-dim);
98
+ margin-bottom: 16px;
99
+ }
100
+
101
+ .phase-track {
102
+ display: flex;
103
+ gap: 4px;
104
+ align-items: center;
105
+ }
106
+
107
+ .phase-step {
108
+ flex: 1;
109
+ text-align: center;
110
+ padding: 10px 8px;
111
+ border-radius: 8px;
112
+ font-size: 9pt;
113
+ font-weight: 600;
114
+ text-transform: uppercase;
115
+ letter-spacing: 0.05em;
116
+ background: var(--bg-card-alt);
117
+ color: var(--text-dim);
118
+ position: relative;
119
+ }
120
+
121
+ .phase-step.done {
122
+ background: var(--green-dim);
123
+ color: var(--green);
124
+ }
125
+
126
+ .phase-step.current {
127
+ background: rgba(59,130,246,0.15);
128
+ color: var(--accent-light);
129
+ box-shadow: 0 0 0 2px var(--accent);
130
+ }
131
+
132
+ .phase-step .count {
133
+ display: block;
134
+ font-size: 16pt;
135
+ font-weight: 800;
136
+ margin-bottom: 2px;
137
+ }
138
+
139
+ .phase-connector {
140
+ width: 20px;
141
+ height: 2px;
142
+ background: var(--text-dim);
143
+ flex-shrink: 0;
144
+ }
145
+
146
+ .phase-connector.done { background: var(--green); }
147
+
148
+ .evidence-row {
149
+ display: flex;
150
+ align-items: center;
151
+ gap: 12px;
152
+ margin-bottom: 10px;
153
+ }
154
+
155
+ .evidence-row .topic {
156
+ width: 140px;
157
+ font-weight: 600;
158
+ color: var(--text);
159
+ font-size: 10pt;
160
+ flex-shrink: 0;
161
+ }
162
+
163
+ .evidence-bar-track {
164
+ flex: 1;
165
+ height: 24px;
166
+ background: var(--bg-card-alt);
167
+ border-radius: 6px;
168
+ overflow: hidden;
169
+ position: relative;
170
+ }
171
+
172
+ .evidence-bar {
173
+ height: 100%;
174
+ border-radius: 6px;
175
+ display: flex;
176
+ align-items: center;
177
+ padding-left: 8px;
178
+ font-size: 8pt;
179
+ font-weight: 700;
180
+ letter-spacing: 0.05em;
181
+ text-transform: uppercase;
182
+ color: rgba(255,255,255,0.9);
183
+ transition: width 0.6s ease;
184
+ }
185
+
186
+ .evidence-bar.production { background: linear-gradient(90deg, #22c55e, #16a34a); }
187
+ .evidence-bar.tested { background: linear-gradient(90deg, #3b82f6, #2563eb); }
188
+ .evidence-bar.documented { background: linear-gradient(90deg, #a78bfa, #7c3aed); }
189
+ .evidence-bar.web { background: linear-gradient(90deg, #f59e0b, #d97706); }
190
+ .evidence-bar.stated { background: linear-gradient(90deg, #64748b, #475569); }
191
+
192
+ .evidence-row .tier-label {
193
+ width: 80px;
194
+ font-size: 9pt;
195
+ color: var(--text-dim);
196
+ text-align: right;
197
+ flex-shrink: 0;
198
+ }
199
+
200
+ .evidence-row .claim-count {
201
+ width: 30px;
202
+ font-size: 9pt;
203
+ color: var(--text-dim);
204
+ text-align: right;
205
+ flex-shrink: 0;
206
+ }
207
+
208
+ .conflict-item {
209
+ padding: 12px 16px;
210
+ margin-bottom: 8px;
211
+ border-radius: 8px;
212
+ border-left: 3px solid var(--red);
213
+ background: var(--red-dim);
214
+ }
215
+
216
+ .conflict-item.resolved {
217
+ border-left-color: var(--green);
218
+ background: var(--green-dim);
219
+ }
220
+
221
+ .conflict-item .conflict-label {
222
+ font-size: 8pt;
223
+ font-weight: 700;
224
+ text-transform: uppercase;
225
+ letter-spacing: 0.08em;
226
+ margin-bottom: 4px;
227
+ }
228
+
229
+ .conflict-item .conflict-label { color: var(--red); }
230
+ .conflict-item.resolved .conflict-label { color: var(--green); }
231
+
232
+ .conflict-item .conflict-text {
233
+ font-size: 10pt;
234
+ color: var(--text-muted);
235
+ line-height: 1.4;
236
+ }
237
+
238
+ .conflict-item .claim-ids {
239
+ font-size: 8pt;
240
+ color: var(--text-dim);
241
+ font-family: monospace;
242
+ margin-top: 4px;
243
+ }
244
+
245
+ .connector-item {
246
+ display: flex;
247
+ align-items: center;
248
+ gap: 10px;
249
+ padding: 8px 0;
250
+ border-bottom: 1px solid var(--border);
251
+ font-size: 10pt;
252
+ color: var(--text-muted);
253
+ }
254
+
255
+ .connector-icon {
256
+ width: 28px;
257
+ height: 28px;
258
+ border-radius: 6px;
259
+ background: rgba(59,130,246,0.12);
260
+ display: flex;
261
+ align-items: center;
262
+ justify-content: center;
263
+ font-size: 12pt;
264
+ flex-shrink: 0;
265
+ }
266
+
267
+ .activity-item {
268
+ display: flex;
269
+ gap: 12px;
270
+ padding: 6px 0;
271
+ border-bottom: 1px solid var(--border);
272
+ font-size: 9pt;
273
+ }
274
+
275
+ .activity-item .time {
276
+ color: var(--text-dim);
277
+ width: 60px;
278
+ flex-shrink: 0;
279
+ font-family: monospace;
280
+ }
281
+
282
+ .activity-item .message {
283
+ color: var(--text-muted);
284
+ }
285
+
286
+ .claim-table {
287
+ width: 100%;
288
+ border-collapse: collapse;
289
+ font-size: 9pt;
290
+ }
291
+
292
+ .claim-table th {
293
+ text-align: left;
294
+ padding: 8px 12px;
295
+ background: var(--bg-card-alt);
296
+ color: var(--text-dim);
297
+ font-weight: 700;
298
+ text-transform: uppercase;
299
+ letter-spacing: 0.06em;
300
+ font-size: 8pt;
301
+ border-bottom: 2px solid var(--border);
302
+ }
303
+
304
+ .claim-table td {
305
+ padding: 8px 12px;
306
+ border-bottom: 1px solid var(--border);
307
+ color: var(--text-muted);
308
+ }
309
+
310
+ .claim-table tr:hover td {
311
+ background: rgba(255,255,255,0.02);
312
+ }
313
+
314
+ .badge {
315
+ display: inline-block;
316
+ padding: 2px 8px;
317
+ border-radius: 4px;
318
+ font-size: 8pt;
319
+ font-weight: 600;
320
+ text-transform: uppercase;
321
+ letter-spacing: 0.04em;
322
+ }
323
+
324
+ .badge.factual { color: var(--accent-light); background: rgba(59,130,246,0.12); }
325
+ .badge.constraint { color: var(--purple); background: rgba(167,139,250,0.12); }
326
+ .badge.estimate { color: var(--orange); background: var(--orange-dim); }
327
+ .badge.risk { color: var(--red); background: var(--red-dim); }
328
+ .badge.recommendation { color: var(--green); background: var(--green-dim); }
329
+ .badge.feedback { color: #f472b6; background: rgba(244,114,182,0.12); }
330
+
331
+ .badge.production { color: var(--green); background: var(--green-dim); }
332
+ .badge.tested { color: var(--accent-light); background: rgba(59,130,246,0.12); }
333
+ .badge.documented { color: var(--purple); background: rgba(167,139,250,0.12); }
334
+ .badge.web { color: var(--orange); background: var(--orange-dim); }
335
+ .badge.stated { color: var(--text-dim); background: rgba(100,116,139,0.15); }
336
+
337
+ .compilation-bar {
338
+ margin-top: 32px;
339
+ padding: 16px 24px;
340
+ background: var(--bg-card);
341
+ border-radius: 8px;
342
+ border: 1px solid var(--border);
343
+ display: flex;
344
+ justify-content: space-between;
345
+ align-items: center;
346
+ font-size: 9pt;
347
+ color: var(--text-dim);
348
+ }
349
+
350
+ .compilation-bar .certificate {
351
+ font-family: monospace;
352
+ font-size: 8pt;
353
+ }
354
+
355
+ .empty-state {
356
+ text-align: center;
357
+ padding: 32px;
358
+ color: var(--text-dim);
359
+ font-style: italic;
360
+ }
361
+
362
+ @media (max-width: 768px) {
363
+ body { padding: 16px; }
364
+ .dashboard-header h1 { font-size: 16pt; }
365
+ .dashboard-header .meta { flex-wrap: wrap; gap: 8px 16px; font-size: 9pt; }
366
+ .grid, .grid.three { grid-template-columns: 1fr; gap: 16px; }
367
+ .panel { padding: 16px; }
368
+ .phase-track { flex-wrap: wrap; gap: 8px; }
369
+ .phase-step { flex: 0 0 calc(50% - 16px); padding: 8px 6px; font-size: 8pt; }
370
+ .phase-step .count { font-size: 14pt; }
371
+ .phase-connector { display: none; }
372
+ .evidence-row { flex-wrap: wrap; gap: 4px 8px; }
373
+ .evidence-row .topic { width: 100%; font-size: 9pt; margin-bottom: -2px; }
374
+ .evidence-bar-track { min-width: 0; }
375
+ .evidence-row .claim-count { width: 24px; font-size: 8pt; }
376
+ .claim-table { font-size: 8pt; }
377
+ .claim-table th, .claim-table td { padding: 6px 8px; }
378
+ .claim-table th:nth-child(4), .claim-table td:nth-child(4) { display: none; }
379
+ .compilation-bar { flex-direction: column; gap: 8px; text-align: center; }
380
+ }
381
+
382
+ @media (max-width: 480px) {
383
+ body { padding: 12px; }
384
+ .dashboard-header h1 { font-size: 14pt; }
385
+ .phase-step { flex: 0 0 calc(50% - 8px); }
386
+ .claim-table th:nth-child(3), .claim-table td:nth-child(3) { display: none; }
387
+ }
388
+ </style>
389
+ </head>
390
+ <body>
391
+
392
+ <!-- TEMPLATE: Populate with data from compilation.json -->
393
+
394
+ <div class="dashboard-header">
395
+ <h1>{{SPRINT_QUESTION}}</h1>
396
+ <div class="meta">
397
+ <span>Phase: <strong>{{PHASE}}</strong></span>
398
+ <span>Claims: <strong>{{TOTAL_CLAIMS}}</strong></span>
399
+ <span>Day {{DAY_COUNT}}</span>
400
+ <span class="status {{STATUS_CLASS}}">{{STATUS}}</span>
401
+ </div>
402
+ </div>
403
+
404
+ <div class="grid full">
405
+ <div class="panel">
406
+ <div class="panel-title">Phase Progress</div>
407
+ <div class="phase-track">
408
+ <div class="phase-step done">
409
+ <span class="count">3</span>
410
+ Define
411
+ </div>
412
+ <div class="phase-connector done"></div>
413
+ <div class="phase-step current">
414
+ <span class="count">12</span>
415
+ Research
416
+ </div>
417
+ <div class="phase-connector"></div>
418
+ <div class="phase-step">
419
+ <span class="count">0</span>
420
+ Prototype
421
+ </div>
422
+ <div class="phase-connector"></div>
423
+ <div class="phase-step">
424
+ <span class="count">0</span>
425
+ Evaluate
426
+ </div>
427
+ <div class="phase-connector"></div>
428
+ <div class="phase-step">
429
+ <span class="count">&mdash;</span>
430
+ Compile
431
+ </div>
432
+ </div>
433
+ </div>
434
+ </div>
435
+
436
+ <div class="grid">
437
+ <div class="panel">
438
+ <div class="panel-title">Evidence Strength by Topic</div>
439
+ <div class="evidence-row">
440
+ <div class="topic">{{TOPIC_NAME}}</div>
441
+ <div class="evidence-bar-track">
442
+ <div class="evidence-bar tested" style="width: {{PERCENT}}%">{{TIER}}</div>
443
+ </div>
444
+ <div class="claim-count">{{N}}</div>
445
+ </div>
446
+ </div>
447
+
448
+ <div class="panel">
449
+ <div class="panel-title">Conflicts</div>
450
+ <div class="conflict-item">
451
+ <div class="conflict-label">Unresolved</div>
452
+ <div class="conflict-text">{{DESCRIPTION}}</div>
453
+ <div class="claim-ids">{{CLAIM_A}} vs {{CLAIM_B}}</div>
454
+ </div>
455
+ <div class="conflict-item resolved">
456
+ <div class="conflict-label">Resolved</div>
457
+ <div class="conflict-text">{{DESCRIPTION}}</div>
458
+ <div class="claim-ids">{{WINNER}} over {{LOSER}} — {{REASON}}</div>
459
+ </div>
460
+ </div>
461
+ </div>
462
+
463
+ <div class="grid">
464
+ <div class="panel">
465
+ <div class="panel-title">Connected Sources</div>
466
+ <div class="connector-item">
467
+ <div class="connector-icon">{{ICON}}</div>
468
+ <div>{{CONNECTOR_TARGET}}</div>
469
+ </div>
470
+ </div>
471
+
472
+ <div class="panel">
473
+ <div class="panel-title">Recent Activity</div>
474
+ <div class="activity-item">
475
+ <div class="time">{{TIME}}</div>
476
+ <div class="message">{{COMMIT_MESSAGE}}</div>
477
+ </div>
478
+ </div>
479
+ </div>
480
+
481
+ <div class="grid full">
482
+ <div class="panel">
483
+ <div class="panel-title">Claim Inventory</div>
484
+ <table class="claim-table">
485
+ <thead>
486
+ <tr>
487
+ <th>ID</th>
488
+ <th>Type</th>
489
+ <th>Topic</th>
490
+ <th>Content</th>
491
+ <th>Evidence</th>
492
+ <th>Status</th>
493
+ </tr>
494
+ </thead>
495
+ <tbody>
496
+ <tr>
497
+ <td><code>{{ID}}</code></td>
498
+ <td><span class="badge {{TYPE}}">{{TYPE}}</span></td>
499
+ <td>{{TOPIC}}</td>
500
+ <td>{{CONTENT}}</td>
501
+ <td><span class="badge {{EVIDENCE}}">{{EVIDENCE}}</span></td>
502
+ <td>{{STATUS}}</td>
503
+ </tr>
504
+ </tbody>
505
+ </table>
506
+ </div>
507
+ </div>
508
+
509
+ <div class="compilation-bar">
510
+ <div>Compiled with barn</div>
511
+ <div class="certificate">{{CERTIFICATE_HASH}}</div>
512
+ </div>
513
+
514
+ </body>
515
+ </html>
@@ -0,0 +1,22 @@
1
+ {
2
+ "title": "Dashboard",
3
+ "description": "Three-layer status dashboard with tables, cards, and CSS variables. Dark theme with scroll-snap sections.",
4
+ "tags": ["status", "dashboard", "tables", "cards", "dark-theme"],
5
+ "author": "grainulation",
6
+ "version": "1.0.0",
7
+ "exportPresets": [
8
+ { "name": "pdf-landscape", "format": "pdf" },
9
+ { "name": "static-site", "format": "html" }
10
+ ],
11
+ "seedPacks": [
12
+ "sprint-metrics",
13
+ "claim-summaries"
14
+ ],
15
+ "scaffoldConfig": {
16
+ "defaultPlaceholders": {
17
+ "TITLE": "Sprint Dashboard",
18
+ "SUBTITLE": "Status Overview"
19
+ },
20
+ "postInit": ["detect-sprints", "load-claims"]
21
+ }
22
+ }