@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
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
<h1>Phases</h1>
|
|
3
3
|
|
|
4
4
|
<% if (phases.length === 0) { %>
|
|
5
|
-
<
|
|
6
|
-
<
|
|
7
|
-
|
|
5
|
+
<div class="card mb-3">
|
|
6
|
+
<div class="card-body">
|
|
7
|
+
<p>No phases found. Add a ROADMAP.md file to your .planning/ directory to see phases here.</p>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
8
10
|
<% } else { %>
|
|
9
11
|
|
|
10
12
|
<%
|
|
@@ -20,20 +22,28 @@
|
|
|
20
22
|
%>
|
|
21
23
|
|
|
22
24
|
<!-- Summary -->
|
|
23
|
-
<
|
|
24
|
-
<header><strong>Summary</strong></
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
<div class="card mb-3">
|
|
26
|
+
<div class="card-header"><strong>Summary</strong></div>
|
|
27
|
+
<div class="card-body">
|
|
28
|
+
<p>
|
|
29
|
+
<%= phases.filter(p => p.status === 'complete').length %> of <%= phases.length %> phases complete<%= milestoneGroups.length > 0 ? ' across ' + milestoneGroups.length + ' milestone' + (milestoneGroups.length !== 1 ? 's' : '') : '' %>.
|
|
30
|
+
</p>
|
|
31
|
+
<div class="progress" style="height:0.5rem">
|
|
32
|
+
<div class="progress-bar" role="progressbar"
|
|
33
|
+
style="width:<%= phases.filter(p => p.status === 'complete').length / phases.length * 100 %>%"
|
|
34
|
+
aria-valuenow="<%= phases.filter(p => p.status === 'complete').length %>"
|
|
35
|
+
aria-valuemin="0" aria-valuemax="<%= phases.length %>">
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
30
40
|
|
|
31
41
|
<% milestoneGroups.forEach(function(group) { %>
|
|
32
|
-
<
|
|
33
|
-
<header>
|
|
42
|
+
<div class="card mb-3">
|
|
43
|
+
<div class="card-header">
|
|
34
44
|
<strong><%= group.name %></strong>
|
|
35
|
-
<small>(Phases <%= String(group.startPhase).padStart(2, '0') %>–<%= String(group.endPhase).padStart(2, '0') %>)</small>
|
|
36
|
-
—
|
|
45
|
+
<small class="ms-1">(Phases <%= String(group.startPhase).padStart(2, '0') %>–<%= String(group.endPhase).padStart(2, '0') %>)</small>
|
|
46
|
+
—
|
|
37
47
|
<%
|
|
38
48
|
const groupComplete = group.phases.filter(p => p.status === 'complete').length;
|
|
39
49
|
const groupTotal = group.phases.length;
|
|
@@ -41,83 +51,87 @@
|
|
|
41
51
|
<span class="status-badge" data-status="<%= groupComplete === groupTotal ? 'complete' : (groupComplete > 0 ? 'in-progress' : 'not-started') %>">
|
|
42
52
|
<%= groupComplete %>/<%= groupTotal %>
|
|
43
53
|
</span>
|
|
44
|
-
</header>
|
|
45
|
-
<% if (group.goal) { %>
|
|
46
|
-
<p><small><%= group.goal %></small></p>
|
|
47
|
-
<% } %>
|
|
48
|
-
<div class="table-wrap">
|
|
49
|
-
<table>
|
|
50
|
-
<thead>
|
|
51
|
-
<tr>
|
|
52
|
-
<th scope="col">Phase</th>
|
|
53
|
-
<th scope="col">Name</th>
|
|
54
|
-
<th scope="col">Plans</th>
|
|
55
|
-
<th scope="col">Status</th>
|
|
56
|
-
</tr>
|
|
57
|
-
</thead>
|
|
58
|
-
<tbody>
|
|
59
|
-
<% group.phases.forEach(function(phase) { %>
|
|
60
|
-
<tr>
|
|
61
|
-
<td><%= String(phase.id).padStart(2, '0') %></td>
|
|
62
|
-
<td>
|
|
63
|
-
<a href="/phases/<%= String(phase.id).padStart(2, '0') %>"
|
|
64
|
-
hx-get="/phases/<%= String(phase.id).padStart(2, '0') %>"
|
|
65
|
-
hx-target="#main-content"
|
|
66
|
-
hx-push-url="true">
|
|
67
|
-
<%= phase.name %>
|
|
68
|
-
</a>
|
|
69
|
-
</td>
|
|
70
|
-
<td><%= phase.planCount %></td>
|
|
71
|
-
<td>
|
|
72
|
-
<span class="status-badge" data-status="<%= phase.status %>">
|
|
73
|
-
<%= phase.status.replace('-', ' ') %>
|
|
74
|
-
</span>
|
|
75
|
-
</td>
|
|
76
|
-
</tr>
|
|
77
|
-
<% }); %>
|
|
78
|
-
</tbody>
|
|
79
|
-
</table>
|
|
80
54
|
</div>
|
|
81
|
-
|
|
55
|
+
<div class="card-body">
|
|
56
|
+
<% if (group.goal) { %>
|
|
57
|
+
<p><small><%= group.goal %></small></p>
|
|
58
|
+
<% } %>
|
|
59
|
+
<div class="table-responsive">
|
|
60
|
+
<table class="table table-vcenter table-hover">
|
|
61
|
+
<thead>
|
|
62
|
+
<tr>
|
|
63
|
+
<th scope="col">Phase</th>
|
|
64
|
+
<th scope="col">Name</th>
|
|
65
|
+
<th scope="col">Plans</th>
|
|
66
|
+
<th scope="col">Status</th>
|
|
67
|
+
</tr>
|
|
68
|
+
</thead>
|
|
69
|
+
<tbody>
|
|
70
|
+
<% group.phases.forEach(function(phase) { %>
|
|
71
|
+
<tr>
|
|
72
|
+
<td><%= String(phase.id).padStart(2, '0') %></td>
|
|
73
|
+
<td>
|
|
74
|
+
<a href="/phases/<%= String(phase.id).padStart(2, '0') %>"
|
|
75
|
+
hx-get="/phases/<%= String(phase.id).padStart(2, '0') %>"
|
|
76
|
+
hx-target="#main-content"
|
|
77
|
+
hx-push-url="true">
|
|
78
|
+
<%= phase.name %>
|
|
79
|
+
</a>
|
|
80
|
+
</td>
|
|
81
|
+
<td><%= phase.planCount %></td>
|
|
82
|
+
<td>
|
|
83
|
+
<span class="status-badge" data-status="<%= phase.status %>">
|
|
84
|
+
<%= phase.status.replace('-', ' ') %>
|
|
85
|
+
</span>
|
|
86
|
+
</td>
|
|
87
|
+
</tr>
|
|
88
|
+
<% }); %>
|
|
89
|
+
</tbody>
|
|
90
|
+
</table>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
82
94
|
<% }); %>
|
|
83
95
|
|
|
84
96
|
<% if (ungrouped.length > 0) { %>
|
|
85
|
-
<
|
|
86
|
-
<header><strong>Other Phases</strong></
|
|
87
|
-
<div class="
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<
|
|
112
|
-
<%= phase.status
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
97
|
+
<div class="card mb-3">
|
|
98
|
+
<div class="card-header"><strong>Other Phases</strong></div>
|
|
99
|
+
<div class="card-body">
|
|
100
|
+
<div class="table-responsive">
|
|
101
|
+
<table class="table table-vcenter table-hover">
|
|
102
|
+
<thead>
|
|
103
|
+
<tr>
|
|
104
|
+
<th scope="col">Phase</th>
|
|
105
|
+
<th scope="col">Name</th>
|
|
106
|
+
<th scope="col">Plans</th>
|
|
107
|
+
<th scope="col">Status</th>
|
|
108
|
+
</tr>
|
|
109
|
+
</thead>
|
|
110
|
+
<tbody>
|
|
111
|
+
<% ungrouped.forEach(function(phase) { %>
|
|
112
|
+
<tr>
|
|
113
|
+
<td><%= String(phase.id).padStart(2, '0') %></td>
|
|
114
|
+
<td>
|
|
115
|
+
<a href="/phases/<%= String(phase.id).padStart(2, '0') %>"
|
|
116
|
+
hx-get="/phases/<%= String(phase.id).padStart(2, '0') %>"
|
|
117
|
+
hx-target="#main-content"
|
|
118
|
+
hx-push-url="true">
|
|
119
|
+
<%= phase.name %>
|
|
120
|
+
</a>
|
|
121
|
+
</td>
|
|
122
|
+
<td><%= phase.planCount %></td>
|
|
123
|
+
<td>
|
|
124
|
+
<span class="status-badge" data-status="<%= phase.status %>">
|
|
125
|
+
<%= phase.status.replace('-', ' ') %>
|
|
126
|
+
</span>
|
|
127
|
+
</td>
|
|
128
|
+
</tr>
|
|
129
|
+
<% }); %>
|
|
130
|
+
</tbody>
|
|
131
|
+
</table>
|
|
132
|
+
</div>
|
|
119
133
|
</div>
|
|
120
|
-
</
|
|
134
|
+
</div>
|
|
121
135
|
<% } %>
|
|
122
136
|
|
|
123
137
|
<% } %>
|
|
@@ -2,39 +2,41 @@
|
|
|
2
2
|
<h1>Quick Tasks</h1>
|
|
3
3
|
|
|
4
4
|
<% if (typeof tasks !== 'undefined' && tasks.length > 0) { %>
|
|
5
|
-
<
|
|
6
|
-
<div class="
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
<%= task.status %>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
5
|
+
<div class="card">
|
|
6
|
+
<div class="card-body p-0">
|
|
7
|
+
<div class="table-responsive">
|
|
8
|
+
<table class="table table-vcenter card-table">
|
|
9
|
+
<thead>
|
|
10
|
+
<tr>
|
|
11
|
+
<th scope="col">ID</th>
|
|
12
|
+
<th scope="col">Title</th>
|
|
13
|
+
<th scope="col">Status</th>
|
|
14
|
+
</tr>
|
|
15
|
+
</thead>
|
|
16
|
+
<tbody>
|
|
17
|
+
<% tasks.forEach(function(task) { %>
|
|
18
|
+
<tr>
|
|
19
|
+
<td><%= task.id %></td>
|
|
20
|
+
<td>
|
|
21
|
+
<a href="/quick/<%= task.id %>"
|
|
22
|
+
hx-get="/quick/<%= task.id %>"
|
|
23
|
+
hx-target="#main-content"
|
|
24
|
+
hx-push-url="true">
|
|
25
|
+
<%= task.title %>
|
|
26
|
+
</a>
|
|
27
|
+
</td>
|
|
28
|
+
<td>
|
|
29
|
+
<span class="status-badge" data-status="<%= task.status %>">
|
|
30
|
+
<%= task.status %>
|
|
31
|
+
</span>
|
|
32
|
+
</td>
|
|
33
|
+
</tr>
|
|
34
|
+
<% }); %>
|
|
35
|
+
</tbody>
|
|
36
|
+
</table>
|
|
37
|
+
</div>
|
|
36
38
|
</div>
|
|
37
|
-
</
|
|
39
|
+
</div>
|
|
38
40
|
<% } else { %>
|
|
39
41
|
<%- include('empty-state', { icon: '⚡', title: 'No quick tasks found', action: '' }) %>
|
|
40
42
|
<% } %>
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
<%- include('breadcrumbs', { breadcrumbs: typeof breadcrumbs !== 'undefined' ? breadcrumbs : [] }) %>
|
|
2
2
|
<h1><%= title %></h1>
|
|
3
3
|
|
|
4
|
-
<p><a href="/quick">← Back to Quick Tasks</a></p>
|
|
4
|
+
<p><a href="/quick" class="btn btn-outline-secondary">← Back to Quick Tasks</a></p>
|
|
5
5
|
|
|
6
|
-
<
|
|
7
|
-
<header>
|
|
6
|
+
<div class="card mb-3">
|
|
7
|
+
<div class="card-header">
|
|
8
8
|
<strong>Quick Task <%= id %></strong>
|
|
9
9
|
|
|
10
10
|
<span class="status-badge" data-status="<%= status %>">
|
|
11
11
|
<%= status %>
|
|
12
12
|
</span>
|
|
13
|
-
</
|
|
13
|
+
</div>
|
|
14
|
+
<div class="card-body">
|
|
15
|
+
<% if (planHtml) { %>
|
|
16
|
+
<section>
|
|
17
|
+
<h2>Plan</h2>
|
|
18
|
+
<%- planHtml %>
|
|
19
|
+
</section>
|
|
20
|
+
<% } %>
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<section>
|
|
25
|
-
<h2>Summary</h2>
|
|
26
|
-
<%- summaryHtml %>
|
|
27
|
-
</section>
|
|
28
|
-
<% } %>
|
|
29
|
-
</article>
|
|
22
|
+
<% if (summaryHtml) { %>
|
|
23
|
+
<hr>
|
|
24
|
+
<section>
|
|
25
|
+
<h2>Summary</h2>
|
|
26
|
+
<%- summaryHtml %>
|
|
27
|
+
</section>
|
|
28
|
+
<% } %>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
@@ -17,19 +17,19 @@
|
|
|
17
17
|
<section class="requirements-section">
|
|
18
18
|
<h2><%= section.sectionTitle %></h2>
|
|
19
19
|
<% section.requirements.forEach(function(req) { %>
|
|
20
|
-
<
|
|
21
|
-
<
|
|
20
|
+
<div class="card mb-2 requirements-card" data-covered="<%= req.covered %>">
|
|
21
|
+
<div class="card-header">
|
|
22
22
|
<code class="req-id"><%= req.id %></code>
|
|
23
23
|
<% if (req.covered) { %>
|
|
24
24
|
<span class="status-badge" data-status="verified">covered</span>
|
|
25
25
|
<% } else { %>
|
|
26
26
|
<span class="status-badge" data-status="warning">uncovered</span>
|
|
27
27
|
<% } %>
|
|
28
|
-
</
|
|
29
|
-
<div class="
|
|
28
|
+
</div>
|
|
29
|
+
<div class="card-body">
|
|
30
30
|
<p><%= req.text %></p>
|
|
31
31
|
<% if (req.planRefs.length > 0) { %>
|
|
32
|
-
<p class="req-plan-refs">
|
|
32
|
+
<p class="req-plan-refs mb-0">
|
|
33
33
|
<small>Plans: </small>
|
|
34
34
|
<% req.planRefs.forEach(function(planId) { %>
|
|
35
35
|
<code class="req-plan-ref"><%= planId %></code>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
</p>
|
|
38
38
|
<% } %>
|
|
39
39
|
</div>
|
|
40
|
-
</
|
|
40
|
+
</div>
|
|
41
41
|
<% }); %>
|
|
42
42
|
</section>
|
|
43
43
|
<% }); %>
|
|
@@ -6,17 +6,17 @@
|
|
|
6
6
|
<%- include('empty-state', { icon: 'R', title: 'No research documents', action: 'Run /pbr:explore or /pbr:scan to generate research.' }) %>
|
|
7
7
|
<% } else { %>
|
|
8
8
|
<% researchDocs.forEach(function(doc) { %>
|
|
9
|
-
<
|
|
10
|
-
<
|
|
9
|
+
<div class="card mb-2">
|
|
10
|
+
<div class="card-header">
|
|
11
11
|
<strong>
|
|
12
12
|
<a href="/research/<%= doc.slug %>"
|
|
13
13
|
hx-get="/research/<%= doc.slug %>"
|
|
14
14
|
hx-target="#main-content"
|
|
15
15
|
hx-push-url="true"><%= doc.title %></a>
|
|
16
16
|
</strong>
|
|
17
|
-
<% if (doc.date) { %><small
|
|
18
|
-
</
|
|
19
|
-
<div class="
|
|
17
|
+
<% if (doc.date) { %><small class="ms-auto text-muted"><%= doc.date %></small><% } %>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="card-body">
|
|
20
20
|
<% if (doc.topic) { %><p><strong>Topic:</strong> <%= doc.topic %></p><% } %>
|
|
21
21
|
<% if (doc.confidence || doc.coverage) { %>
|
|
22
22
|
<p>
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
</p>
|
|
26
26
|
<% } %>
|
|
27
27
|
<% if (!doc.topic && !doc.confidence && !doc.coverage) { %>
|
|
28
|
-
<p class="muted"><small>Click to view full document</small></p>
|
|
28
|
+
<p class="text-muted mb-0"><small>Click to view full document</small></p>
|
|
29
29
|
<% } %>
|
|
30
30
|
</div>
|
|
31
|
-
</
|
|
31
|
+
</div>
|
|
32
32
|
<% }); %>
|
|
33
33
|
<% } %>
|
|
34
34
|
|
|
@@ -37,20 +37,20 @@
|
|
|
37
37
|
<%- include('empty-state', { icon: 'C', title: 'No codebase documents', action: 'Run /pbr:scan to generate codebase analysis.' }) %>
|
|
38
38
|
<% } else { %>
|
|
39
39
|
<% codebaseDocs.forEach(function(doc) { %>
|
|
40
|
-
<
|
|
41
|
-
<
|
|
40
|
+
<div class="card mb-2">
|
|
41
|
+
<div class="card-header">
|
|
42
42
|
<strong>
|
|
43
43
|
<a href="/research/<%= doc.slug %>"
|
|
44
44
|
hx-get="/research/<%= doc.slug %>"
|
|
45
45
|
hx-target="#main-content"
|
|
46
46
|
hx-push-url="true"><%= doc.title %></a>
|
|
47
47
|
</strong>
|
|
48
|
-
<% if (doc.date) { %><small
|
|
49
|
-
</
|
|
50
|
-
<div class="
|
|
48
|
+
<% if (doc.date) { %><small class="ms-auto text-muted"><%= doc.date %></small><% } %>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="card-body">
|
|
51
51
|
<% if (doc.focus) { %><p><strong>Focus:</strong> <%= doc.focus %></p><% } %>
|
|
52
|
-
<% if (!doc.focus) { %><p class="muted"><small>Click to view full document</small></p><% } %>
|
|
52
|
+
<% if (!doc.focus) { %><p class="text-muted mb-0"><small>Click to view full document</small></p><% } %>
|
|
53
53
|
</div>
|
|
54
|
-
</
|
|
54
|
+
</div>
|
|
55
55
|
<% }); %>
|
|
56
56
|
<% } %>
|
|
@@ -2,22 +2,24 @@
|
|
|
2
2
|
<h1><%= title %></h1>
|
|
3
3
|
|
|
4
4
|
<% if (topic || date || confidence || coverage || sources_checked) { %>
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
<div class="card mb-3">
|
|
6
|
+
<div class="card-body">
|
|
7
|
+
<% if (topic) { %><p><strong>Topic:</strong> <%= topic %></p><% } %>
|
|
8
|
+
<% if (date) { %><p><strong>Date:</strong> <%= date %></p><% } %>
|
|
9
|
+
<% if (confidence) { %><p><strong>Confidence:</strong> <span class="status-badge" data-status="<%= confidence %>"><%= confidence %></span></p><% } %>
|
|
10
|
+
<% if (coverage) { %><p><strong>Coverage:</strong> <%= coverage %></p><% } %>
|
|
11
|
+
<% if (sources_checked) { %><p class="mb-0"><strong>Sources checked:</strong> <%= sources_checked %></p><% } %>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
12
14
|
<% } %>
|
|
13
15
|
|
|
14
|
-
<
|
|
15
|
-
<div class="
|
|
16
|
+
<div class="card mb-3">
|
|
17
|
+
<div class="card-body markdown-body">
|
|
16
18
|
<%- html %>
|
|
17
19
|
</div>
|
|
18
|
-
</
|
|
20
|
+
</div>
|
|
19
21
|
|
|
20
|
-
<p><a href="/research"
|
|
22
|
+
<p><a href="/research" class="btn btn-outline-secondary"
|
|
21
23
|
hx-get="/research"
|
|
22
24
|
hx-target="#main-content"
|
|
23
25
|
hx-push-url="true">← Back to Research</a></p>
|