@sienklogic/plan-build-run 2.27.0 → 2.27.2
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/CHANGELOG.md +14 -0
- package/dashboard/public/css/layout.css +7 -283
- package/dashboard/public/css/status-colors.css +7 -0
- package/dashboard/public/css/tokens.css +3 -3
- package/dashboard/public/js/sidebar-toggle.js +9 -31
- package/dashboard/public/js/theme-toggle.js +4 -4
- package/dashboard/src/services/phase.service.js +6 -2
- package/dashboard/src/views/partials/activity-feed.ejs +17 -9
- package/dashboard/src/views/partials/analytics-content.ejs +178 -88
- package/dashboard/src/views/partials/audit-detail-content.ejs +6 -4
- package/dashboard/src/views/partials/audits-content.ejs +28 -26
- package/dashboard/src/views/partials/breadcrumbs.ejs +8 -4
- package/dashboard/src/views/partials/config-content.ejs +98 -95
- package/dashboard/src/views/partials/dashboard-content.ejs +69 -60
- package/dashboard/src/views/partials/dependencies-content.ejs +5 -3
- package/dashboard/src/views/partials/empty-state.ejs +10 -5
- package/dashboard/src/views/partials/footer.ejs +8 -2
- package/dashboard/src/views/partials/head.ejs +2 -1
- package/dashboard/src/views/partials/header.ejs +16 -19
- package/dashboard/src/views/partials/layout-bottom.ejs +5 -40
- package/dashboard/src/views/partials/layout-top.ejs +6 -5
- package/dashboard/src/views/partials/logs-content.ejs +26 -29
- package/dashboard/src/views/partials/milestone-detail-content.ejs +5 -5
- package/dashboard/src/views/partials/milestones-content.ejs +40 -31
- package/dashboard/src/views/partials/note-detail-content.ejs +7 -5
- package/dashboard/src/views/partials/notes-content.ejs +4 -4
- package/dashboard/src/views/partials/phase-content.ejs +6 -8
- package/dashboard/src/views/partials/phase-doc-content.ejs +13 -15
- package/dashboard/src/views/partials/phase-timeline.ejs +22 -15
- package/dashboard/src/views/partials/phases-content.ejs +100 -86
- package/dashboard/src/views/partials/quick-content.ejs +34 -32
- package/dashboard/src/views/partials/quick-detail-content.ejs +20 -19
- package/dashboard/src/views/partials/requirements-content.ejs +6 -6
- package/dashboard/src/views/partials/research-content.ejs +14 -14
- package/dashboard/src/views/partials/research-detail-content.ejs +13 -11
- package/dashboard/src/views/partials/roadmap-content.ejs +149 -132
- package/dashboard/src/views/partials/sidebar.ejs +86 -140
- package/dashboard/src/views/partials/todo-create-content.ejs +51 -46
- package/dashboard/src/views/partials/todo-detail-content.ejs +26 -25
- package/dashboard/src/views/partials/todos-content.ejs +65 -62
- package/dashboard/src/views/partials/todos-done-content.ejs +33 -31
- package/package.json +1 -1
- package/plugins/copilot-pbr/plugin.json +1 -1
- package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
- package/plugins/pbr/.claude-plugin/plugin.json +1 -1
- package/plugins/pbr/scripts/local-llm/metrics.js +121 -33
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ All notable changes to Plan-Build-Run will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.27.2](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.27.1...plan-build-run-v2.27.2) (2026-02-24)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **37-05:** fix breadcrumb icon, milestone spacing, summary lookup, and config mode dropdown ([fd6d929](https://github.com/SienkLogic/plan-build-run/commit/fd6d92947c708e0aaba4b3d0a18897228e1957ec))
|
|
14
|
+
|
|
15
|
+
## [2.27.1](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.27.0...plan-build-run-v2.27.1) (2026-02-24)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **tools:** prevent lifetime LLM metrics from plateauing at 200 entries ([2cbdaa4](https://github.com/SienkLogic/plan-build-run/commit/2cbdaa4b4402110cc4bb0f6505d034f2162aa782))
|
|
21
|
+
|
|
8
22
|
## [2.27.0](https://github.com/SienkLogic/plan-build-run/compare/plan-build-run-v2.26.2...plan-build-run-v2.27.0) (2026-02-24)
|
|
9
23
|
|
|
10
24
|
|
|
@@ -27,103 +27,6 @@ p { line-height: 1.65; }
|
|
|
27
27
|
|
|
28
28
|
small { font-size: 0.8125rem; color: var(--color-text-dim); }
|
|
29
29
|
|
|
30
|
-
/* --- Page Grid Layout --- */
|
|
31
|
-
.page-wrapper {
|
|
32
|
-
display: grid;
|
|
33
|
-
gap: 0;
|
|
34
|
-
grid-template-columns: var(--size-sidebar) 1fr;
|
|
35
|
-
grid-template-rows: var(--size-header) 1fr auto;
|
|
36
|
-
grid-template-areas:
|
|
37
|
-
"header header"
|
|
38
|
-
"sidebar content"
|
|
39
|
-
"footer footer";
|
|
40
|
-
min-height: 100vh;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/* --- Header --- */
|
|
44
|
-
.page-wrapper > header {
|
|
45
|
-
grid-area: header;
|
|
46
|
-
display: flex;
|
|
47
|
-
align-items: center;
|
|
48
|
-
padding: 0 var(--space-xl);
|
|
49
|
-
border-bottom: 1px solid var(--color-border);
|
|
50
|
-
background: var(--color-surface-raised);
|
|
51
|
-
backdrop-filter: blur(8px);
|
|
52
|
-
position: sticky;
|
|
53
|
-
top: 0;
|
|
54
|
-
z-index: 10;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.page-wrapper > header nav {
|
|
58
|
-
display: flex;
|
|
59
|
-
justify-content: space-between;
|
|
60
|
-
align-items: center;
|
|
61
|
-
width: 100%;
|
|
62
|
-
margin: 0;
|
|
63
|
-
padding: 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.page-wrapper > header nav strong {
|
|
67
|
-
font-size: 1rem;
|
|
68
|
-
font-weight: 600;
|
|
69
|
-
letter-spacing: -0.02em;
|
|
70
|
-
white-space: nowrap;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.page-wrapper > header nav ul {
|
|
74
|
-
list-style: none;
|
|
75
|
-
margin: 0;
|
|
76
|
-
padding: 0;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/* --- Sidebar --- */
|
|
80
|
-
.page-wrapper > aside.sidebar {
|
|
81
|
-
grid-area: sidebar;
|
|
82
|
-
padding: var(--space-lg) 0;
|
|
83
|
-
border-right: 1px solid var(--color-border);
|
|
84
|
-
background: var(--color-surface-raised);
|
|
85
|
-
position: sticky;
|
|
86
|
-
top: var(--size-header);
|
|
87
|
-
height: calc(100vh - var(--size-header));
|
|
88
|
-
overflow-y: auto;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
aside.sidebar nav ul {
|
|
92
|
-
list-style: none;
|
|
93
|
-
padding: 0;
|
|
94
|
-
margin: 0;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
aside.sidebar nav li {
|
|
98
|
-
margin: 0;
|
|
99
|
-
padding: 0;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
aside.sidebar nav a {
|
|
103
|
-
display: flex;
|
|
104
|
-
align-items: center;
|
|
105
|
-
padding: 0.6rem var(--space-lg);
|
|
106
|
-
text-decoration: none;
|
|
107
|
-
border-left: 3px solid transparent;
|
|
108
|
-
font-size: 0.9rem;
|
|
109
|
-
font-weight: 500;
|
|
110
|
-
color: var(--color-text-dim);
|
|
111
|
-
transition: all var(--transition-fast);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
aside.sidebar nav a:hover {
|
|
115
|
-
color: var(--pico-color);
|
|
116
|
-
background: var(--color-surface-hover);
|
|
117
|
-
border-left-color: var(--color-border);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
aside.sidebar nav a[aria-current="page"] {
|
|
121
|
-
font-weight: 600;
|
|
122
|
-
color: var(--color-accent);
|
|
123
|
-
border-left-color: var(--color-accent);
|
|
124
|
-
background: var(--color-surface-hover);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
30
|
/* --- Sidebar: Current Phase Card --- */
|
|
128
31
|
.sidebar-current-phase {
|
|
129
32
|
padding: var(--space-md) var(--space-lg);
|
|
@@ -188,59 +91,6 @@ aside.sidebar nav a[aria-current="page"] {
|
|
|
188
91
|
white-space: nowrap;
|
|
189
92
|
}
|
|
190
93
|
|
|
191
|
-
/* --- Sidebar: Section Details --- */
|
|
192
|
-
aside.sidebar details {
|
|
193
|
-
border: none;
|
|
194
|
-
margin: 0;
|
|
195
|
-
padding: 0;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
aside.sidebar details + details {
|
|
199
|
-
margin-top: var(--space-xs);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
aside.sidebar details summary {
|
|
203
|
-
text-transform: uppercase;
|
|
204
|
-
font-size: 0.6875rem;
|
|
205
|
-
font-weight: 600;
|
|
206
|
-
letter-spacing: 0.06em;
|
|
207
|
-
color: var(--color-text-dim);
|
|
208
|
-
padding: var(--space-xs) var(--space-lg);
|
|
209
|
-
cursor: pointer;
|
|
210
|
-
border-left: 3px solid transparent;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
aside.sidebar details[open] summary {
|
|
214
|
-
color: var(--color-accent);
|
|
215
|
-
border-left-color: var(--color-accent);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
aside.sidebar details ul {
|
|
219
|
-
margin: 0;
|
|
220
|
-
padding-bottom: var(--space-xs);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/* --- Main Content --- */
|
|
224
|
-
.page-wrapper > main {
|
|
225
|
-
grid-area: content;
|
|
226
|
-
padding: var(--space-xl) var(--space-2xl);
|
|
227
|
-
overflow-y: auto;
|
|
228
|
-
max-width: calc(var(--content-max-width) + var(--space-2xl) * 2);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/* --- Footer --- */
|
|
232
|
-
.page-wrapper > footer {
|
|
233
|
-
grid-area: footer;
|
|
234
|
-
padding: var(--space-md) var(--space-xl);
|
|
235
|
-
border-top: 1px solid var(--color-border);
|
|
236
|
-
text-align: center;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
.page-wrapper > footer small {
|
|
240
|
-
font-size: 0.75rem;
|
|
241
|
-
color: var(--color-text-dim);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
94
|
/* --- Card Component --- */
|
|
245
95
|
.card,
|
|
246
96
|
article {
|
|
@@ -423,36 +273,6 @@ details li {
|
|
|
423
273
|
margin: var(--space-lg) 0;
|
|
424
274
|
}
|
|
425
275
|
|
|
426
|
-
/* --- Breadcrumbs --- */
|
|
427
|
-
.breadcrumbs {
|
|
428
|
-
display: flex;
|
|
429
|
-
list-style: none;
|
|
430
|
-
padding: 0;
|
|
431
|
-
margin: 0 0 var(--space-md) 0;
|
|
432
|
-
font-size: 0.85rem;
|
|
433
|
-
gap: var(--space-xs);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
.breadcrumbs li + li::before {
|
|
437
|
-
content: ">";
|
|
438
|
-
margin-right: var(--space-xs);
|
|
439
|
-
color: var(--color-text-dim);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
.breadcrumbs a {
|
|
443
|
-
color: var(--color-accent);
|
|
444
|
-
text-decoration: none;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
.breadcrumbs a:hover {
|
|
448
|
-
text-decoration: underline;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
.breadcrumbs [aria-current="page"] {
|
|
452
|
-
color: var(--color-text-dim);
|
|
453
|
-
font-weight: 500;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
276
|
/* --- Phase Timeline (homepage) --- */
|
|
457
277
|
.phase-timeline {
|
|
458
278
|
list-style: none;
|
|
@@ -586,8 +406,8 @@ main > p:first-of-type > a[href="/"]:hover {
|
|
|
586
406
|
top: 0;
|
|
587
407
|
z-index: 1000;
|
|
588
408
|
padding: var(--space-sm) var(--space-md);
|
|
589
|
-
background: var(--
|
|
590
|
-
color: var(--
|
|
409
|
+
background: var(--tblr-primary);
|
|
410
|
+
color: var(--tblr-primary-fg, #fff);
|
|
591
411
|
text-decoration: none;
|
|
592
412
|
font-weight: 600;
|
|
593
413
|
}
|
|
@@ -600,24 +420,13 @@ main > p:first-of-type > a[href="/"]:hover {
|
|
|
600
420
|
|
|
601
421
|
/* --- Focus Visible --- */
|
|
602
422
|
:focus-visible {
|
|
603
|
-
outline: 2px solid var(--
|
|
423
|
+
outline: 2px solid var(--tblr-primary);
|
|
604
424
|
outline-offset: 2px;
|
|
605
425
|
}
|
|
606
426
|
|
|
607
|
-
/* --- Empty State --- */
|
|
608
|
-
.empty-state {
|
|
609
|
-
text-align: center;
|
|
610
|
-
padding: var(--space-2xl) var(--space-lg);
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
.empty-state h3 {
|
|
614
|
-
color: var(--color-text-dim);
|
|
615
|
-
font-weight: 500;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
427
|
/* --- Error Card --- */
|
|
619
428
|
.error-card {
|
|
620
|
-
border-left: 4px solid var(--
|
|
429
|
+
border-left: 4px solid var(--tblr-danger);
|
|
621
430
|
padding: var(--space-lg);
|
|
622
431
|
margin: var(--space-lg) 0;
|
|
623
432
|
background: var(--color-surface-raised);
|
|
@@ -659,7 +468,7 @@ main > p:first-of-type > a[href="/"]:hover {
|
|
|
659
468
|
/* --- Bar Chart --- */
|
|
660
469
|
.bar-chart-row { display: flex; align-items: center; gap: var(--space-sm); margin-bottom: var(--space-xs); }
|
|
661
470
|
.bar-chart-label { min-width: 160px; font-size: 0.875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
662
|
-
.bar-chart-bar { height: 1.5rem; border-radius: var(--radius-sm); background: var(--
|
|
471
|
+
.bar-chart-bar { height: 1.5rem; border-radius: var(--radius-sm); background: var(--tblr-primary); color: var(--tblr-primary-fg, #fff); font-size: 0.75rem; display: flex; align-items: center; padding-left: var(--space-sm); min-width: 2rem; transition: width var(--transition-base); }
|
|
663
472
|
|
|
664
473
|
/* --- Loading Bar --- */
|
|
665
474
|
.loading-bar {
|
|
@@ -674,7 +483,7 @@ main > p:first-of-type > a[href="/"]:hover {
|
|
|
674
483
|
|
|
675
484
|
.htmx-request .loading-bar {
|
|
676
485
|
display: block;
|
|
677
|
-
background: var(--
|
|
486
|
+
background: var(--tblr-primary);
|
|
678
487
|
animation: loading-shimmer 1.2s ease-in-out infinite;
|
|
679
488
|
}
|
|
680
489
|
|
|
@@ -683,93 +492,12 @@ main > p:first-of-type > a[href="/"]:hover {
|
|
|
683
492
|
100% { transform: translateX(100%); }
|
|
684
493
|
}
|
|
685
494
|
|
|
686
|
-
/* --- Sidebar Backdrop (hidden by default, shown on mobile) --- */
|
|
687
|
-
.sidebar-backdrop {
|
|
688
|
-
display: none;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
/* --- Mobile hamburger toggle --- */
|
|
692
|
-
.sidebar-toggle {
|
|
693
|
-
display: none;
|
|
694
|
-
background: none;
|
|
695
|
-
border: 1px solid var(--color-border);
|
|
696
|
-
border-radius: var(--radius-sm);
|
|
697
|
-
color: var(--pico-color);
|
|
698
|
-
font-size: 1.25rem;
|
|
699
|
-
padding: 0.25rem 0.5rem;
|
|
700
|
-
cursor: pointer;
|
|
701
|
-
line-height: 1;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
495
|
/* ============================================
|
|
705
496
|
Responsive Breakpoints
|
|
706
497
|
============================================ */
|
|
707
498
|
|
|
708
|
-
/*
|
|
709
|
-
@media (max-width: 1024px) {
|
|
710
|
-
:root {
|
|
711
|
-
--size-sidebar: 180px;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
.page-wrapper > main {
|
|
715
|
-
padding: var(--space-lg) var(--space-xl);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
/* Mobile: sidebar overlays content */
|
|
499
|
+
/* Mobile: compact typography */
|
|
720
500
|
@media (max-width: 768px) {
|
|
721
|
-
.page-wrapper {
|
|
722
|
-
grid-template-columns: 1fr;
|
|
723
|
-
grid-template-rows: var(--size-header) 1fr auto;
|
|
724
|
-
grid-template-areas:
|
|
725
|
-
"header"
|
|
726
|
-
"content"
|
|
727
|
-
"footer";
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
.sidebar-toggle {
|
|
731
|
-
display: block;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
.page-wrapper > aside.sidebar {
|
|
735
|
-
position: fixed;
|
|
736
|
-
top: var(--size-header);
|
|
737
|
-
left: 0;
|
|
738
|
-
width: 260px;
|
|
739
|
-
height: calc(100vh - var(--size-header));
|
|
740
|
-
z-index: 20;
|
|
741
|
-
transform: translateX(-100%);
|
|
742
|
-
transition: var(--transition-transform);
|
|
743
|
-
display: block;
|
|
744
|
-
border-right: 1px solid var(--color-border);
|
|
745
|
-
border-bottom: none;
|
|
746
|
-
padding: var(--space-lg) 0;
|
|
747
|
-
overflow-y: auto;
|
|
748
|
-
background: var(--pico-background-color, var(--color-dark-surface));
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
.page-wrapper > aside.sidebar.open {
|
|
752
|
-
transform: translateX(0);
|
|
753
|
-
box-shadow: 4px 0 24px var(--overlay-bg);
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
.sidebar-backdrop {
|
|
757
|
-
display: none;
|
|
758
|
-
position: fixed;
|
|
759
|
-
inset: 0;
|
|
760
|
-
top: var(--size-header);
|
|
761
|
-
background: var(--overlay-bg-heavy);
|
|
762
|
-
z-index: 19;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
.sidebar-backdrop.open {
|
|
766
|
-
display: block;
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
.page-wrapper > main {
|
|
770
|
-
padding: var(--space-lg) var(--space-md);
|
|
771
|
-
}
|
|
772
|
-
|
|
773
501
|
h1 { font-size: 1.4rem; }
|
|
774
502
|
h2 { font-size: 1.15rem; }
|
|
775
503
|
|
|
@@ -810,10 +538,6 @@ main > p:first-of-type > a[href="/"]:hover {
|
|
|
810
538
|
font-size: 14px;
|
|
811
539
|
}
|
|
812
540
|
|
|
813
|
-
.page-wrapper > main {
|
|
814
|
-
padding: var(--space-md);
|
|
815
|
-
}
|
|
816
|
-
|
|
817
541
|
article > header {
|
|
818
542
|
padding: var(--space-sm) var(--space-md);
|
|
819
543
|
}
|
|
@@ -97,6 +97,13 @@
|
|
|
97
97
|
border-color: rgba(129, 140, 248, 0.2);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/* Tabler .badge compatibility shim */
|
|
101
|
+
.badge.status-badge {
|
|
102
|
+
font-size: var(--badge-font-size-base);
|
|
103
|
+
font-weight: 600;
|
|
104
|
+
letter-spacing: 0.02em;
|
|
105
|
+
}
|
|
106
|
+
|
|
100
107
|
/* Size variants */
|
|
101
108
|
.status-badge--sm {
|
|
102
109
|
padding: var(--badge-padding-sm);
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
--color-border: rgba(0, 0, 0, 0.1);
|
|
14
14
|
--color-text-dim: rgba(0, 0, 0, 0.5);
|
|
15
15
|
--color-text: #1a1a2e;
|
|
16
|
-
--color-accent: var(--
|
|
16
|
+
--color-accent: var(--tblr-primary, #0054a6);
|
|
17
17
|
|
|
18
18
|
/* Spacing */
|
|
19
19
|
--space-xs: 0.25rem;
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/* --- Dark Mode (explicit attribute) --- */
|
|
76
|
-
[data-theme="dark"] {
|
|
76
|
+
[data-bs-theme="dark"] {
|
|
77
77
|
--color-surface: #13131a;
|
|
78
78
|
--color-surface-raised: rgba(255, 255, 255, 0.03);
|
|
79
79
|
--color-surface-hover: rgba(255, 255, 255, 0.06);
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
|
|
85
85
|
/* --- Dark Mode (system preference, unless light forced) --- */
|
|
86
86
|
@media (prefers-color-scheme: dark) {
|
|
87
|
-
:root:not([data-theme="light"]) {
|
|
87
|
+
:root:not([data-bs-theme="light"]) {
|
|
88
88
|
--color-surface: #13131a;
|
|
89
89
|
--color-surface-raised: rgba(255, 255, 255, 0.03);
|
|
90
90
|
--color-surface-hover: rgba(255, 255, 255, 0.06);
|
|
@@ -1,34 +1,12 @@
|
|
|
1
|
-
//
|
|
1
|
+
// sidebar-toggle.js — Tabler vertical navbar toggle shim
|
|
2
|
+
// Tabler's Bootstrap JS handles collapse via data-bs-toggle="collapse".
|
|
3
|
+
// This file remains for the header button (#sidebar-toggle) which triggers
|
|
4
|
+
// the .navbar-vertical collapse on mobile.
|
|
2
5
|
document.addEventListener('DOMContentLoaded', function() {
|
|
3
|
-
var toggle = document.
|
|
4
|
-
var
|
|
5
|
-
if (!toggle || !
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var backdrop = document.createElement('div');
|
|
9
|
-
backdrop.className = 'sidebar-backdrop';
|
|
10
|
-
document.body.appendChild(backdrop);
|
|
11
|
-
|
|
12
|
-
function closeSidebar() {
|
|
13
|
-
sidebar.classList.remove('open');
|
|
14
|
-
backdrop.classList.remove('open');
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function toggleSidebar() {
|
|
18
|
-
sidebar.classList.toggle('open');
|
|
19
|
-
backdrop.classList.toggle('open');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
toggle.addEventListener('click', toggleSidebar);
|
|
23
|
-
backdrop.addEventListener('click', closeSidebar);
|
|
24
|
-
|
|
25
|
-
// Close sidebar when a nav link is clicked (mobile)
|
|
26
|
-
var navLinks = sidebar.querySelectorAll('a');
|
|
27
|
-
navLinks.forEach(function(link) {
|
|
28
|
-
link.addEventListener('click', function() {
|
|
29
|
-
if (window.innerWidth <= 768) {
|
|
30
|
-
closeSidebar();
|
|
31
|
-
}
|
|
32
|
-
});
|
|
6
|
+
var toggle = document.getElementById('sidebar-toggle');
|
|
7
|
+
var sidebarMenu = document.getElementById('sidebar-menu');
|
|
8
|
+
if (!toggle || !sidebarMenu) return;
|
|
9
|
+
toggle.addEventListener('click', function() {
|
|
10
|
+
sidebarMenu.classList.toggle('show');
|
|
33
11
|
});
|
|
34
12
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/* theme-toggle.js — Toggle light/dark theme via data-theme attribute + localStorage */
|
|
1
|
+
/* theme-toggle.js — Toggle light/dark theme via data-bs-theme attribute + localStorage */
|
|
2
2
|
(function () {
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
5
|
var STORAGE_KEY = 'pbr-theme';
|
|
6
6
|
|
|
7
7
|
function getEffectiveTheme() {
|
|
8
|
-
var explicit = document.documentElement.dataset.
|
|
8
|
+
var explicit = document.documentElement.dataset.bsTheme;
|
|
9
9
|
if (explicit === 'light' || explicit === 'dark') return explicit;
|
|
10
10
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
11
11
|
}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
// Apply stored theme (also done in layout-top inline script for flash prevention)
|
|
24
24
|
var stored = localStorage.getItem(STORAGE_KEY);
|
|
25
25
|
if (stored) {
|
|
26
|
-
document.documentElement.dataset.
|
|
26
|
+
document.documentElement.dataset.bsTheme = stored;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
updateIcon(btn, getEffectiveTheme());
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
btn.addEventListener('click', function () {
|
|
32
32
|
var current = getEffectiveTheme();
|
|
33
33
|
var next = current === 'dark' ? 'light' : 'dark';
|
|
34
|
-
document.documentElement.dataset.
|
|
34
|
+
document.documentElement.dataset.bsTheme = next;
|
|
35
35
|
localStorage.setItem(STORAGE_KEY, next);
|
|
36
36
|
updateIcon(btn, next);
|
|
37
37
|
});
|
|
@@ -159,7 +159,9 @@ export async function getPhaseDetail(projectDir, phaseId) {
|
|
|
159
159
|
const oldMatch = planFile.match(/^(\d{2}-\d{2})-PLAN\.md$/);
|
|
160
160
|
const newMatch = planFile.match(/^PLAN-(\d{2})\.md$/);
|
|
161
161
|
const planId = oldMatch ? oldMatch[1] : newMatch ? `${phaseId.padStart(2, '0')}-${newMatch[1]}` : `${phaseId.padStart(2, '0')}-${String(index + 1).padStart(2, '0')}`;
|
|
162
|
-
|
|
162
|
+
// Summary files use just the sequence number for PLAN-NN.md format (SUMMARY-NN.md)
|
|
163
|
+
const summaryName = newMatch ? `SUMMARY-${newMatch[1]}.md` : `SUMMARY-${planId}.md`;
|
|
164
|
+
return { planId, planFile, summaryPath: join(phaseFullPath, summaryName) };
|
|
163
165
|
});
|
|
164
166
|
|
|
165
167
|
const summaryResults = await Promise.allSettled(
|
|
@@ -257,7 +259,9 @@ export async function getPhaseDocument(projectDir, phaseId, planId, docType) {
|
|
|
257
259
|
} else if (docType === 'verification') {
|
|
258
260
|
fileNames = ['VERIFICATION.md'];
|
|
259
261
|
} else {
|
|
260
|
-
|
|
262
|
+
// Try both formats: SUMMARY-NN.md (sequence only) and SUMMARY-{planId}.md (full ID)
|
|
263
|
+
const seqMatch = planId.match(/^\d{2}-(\d{2})$/);
|
|
264
|
+
fileNames = seqMatch ? [`SUMMARY-${seqMatch[1]}.md`, `SUMMARY-${planId}.md`] : [`SUMMARY-${planId}.md`];
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
for (const fileName of fileNames) {
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
<% if (!recentActivity || recentActivity.length === 0) { %>
|
|
2
|
-
|
|
2
|
+
<%- include('empty-state', { title: 'No recent activity' }) %>
|
|
3
3
|
<% } else { %>
|
|
4
|
-
<
|
|
4
|
+
<div class="list-group list-group-flush">
|
|
5
5
|
<% recentActivity.forEach(function(item) { %>
|
|
6
6
|
<%
|
|
7
7
|
// Format path: strip .planning/ prefix for brevity
|
|
8
|
-
var displayPath = item.path.replace(/^\.planning\//, '');
|
|
8
|
+
var displayPath = (item.path || item.description || String(item)).replace(/^\.planning\//, '');
|
|
9
9
|
// Format timestamp: show just date+time, no timezone
|
|
10
|
-
var ts = item.timestamp || '';
|
|
10
|
+
var ts = item.timestamp || item.time || item.date || '';
|
|
11
11
|
var dateOnly = ts.replace(/\s+[-+]\d{4}$/, '').replace(/:\d{2}$/, '');
|
|
12
12
|
%>
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
<div class="list-group-item">
|
|
14
|
+
<div class="row align-items-center">
|
|
15
|
+
<div class="col text-truncate">
|
|
16
|
+
<span class="text-truncate small"><%= displayPath %></span>
|
|
17
|
+
</div>
|
|
18
|
+
<% if (dateOnly) { %>
|
|
19
|
+
<div class="col-auto">
|
|
20
|
+
<time class="text-muted small" datetime="<%= ts %>"><%= dateOnly %></time>
|
|
21
|
+
</div>
|
|
22
|
+
<% } %>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
17
25
|
<% }); %>
|
|
18
|
-
</
|
|
26
|
+
</div>
|
|
19
27
|
<% } %>
|