bigpowers 2.3.0 → 2.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.
- package/.pi/package.json +1 -1
- package/.pi/prompts/compose-workflow.md +1 -1
- package/.pi/prompts/diagnose-root.md +1 -1
- package/.pi/prompts/evolve-skill.md +1 -1
- package/.pi/prompts/grill-with-docs.md +1 -1
- package/.pi/prompts/research-first.md +1 -1
- package/.pi/prompts/reset-baseline.md +1 -1
- package/.pi/prompts/run-evals.md +1 -1
- package/.pi/prompts/scope-work.md +1 -1
- package/.pi/prompts/search-skills.md +1 -1
- package/.pi/prompts/setup-environment.md +1 -1
- package/.pi/prompts/simulate-agents.md +1 -1
- package/.pi/prompts/slice-tasks.md +1 -1
- package/.pi/prompts/stocktake-skills.md +1 -1
- package/.pi/prompts/verify-work.md +1 -1
- package/.pi/skills/assess-impact/SKILL.md +2 -1
- package/.pi/skills/audit-code/SKILL.md +1 -0
- package/.pi/skills/build-epic/SKILL.md +1 -0
- package/.pi/skills/change-request/SKILL.md +1 -0
- package/.pi/skills/commit-message/SKILL.md +1 -0
- package/.pi/skills/compose-workflow/SKILL.md +2 -1
- package/.pi/skills/craft-skill/SKILL.md +1 -0
- package/.pi/skills/deepen-architecture/SKILL.md +1 -0
- package/.pi/skills/define-language/SKILL.md +2 -1
- package/.pi/skills/define-success/SKILL.md +2 -1
- package/.pi/skills/delegate-task/SKILL.md +1 -0
- package/.pi/skills/design-interface/SKILL.md +2 -1
- package/.pi/skills/develop-tdd/SKILL.md +1 -0
- package/.pi/skills/diagnose-root/SKILL.md +2 -1
- package/.pi/skills/dispatch-agents/SKILL.md +1 -0
- package/.pi/skills/edit-document/SKILL.md +1 -0
- package/.pi/skills/elaborate-spec/SKILL.md +2 -1
- package/.pi/skills/enforce-first/SKILL.md +2 -1
- package/.pi/skills/evolve-skill/SKILL.md +2 -1
- package/.pi/skills/execute-plan/SKILL.md +1 -0
- package/.pi/skills/fix-bug/SKILL.md +1 -0
- package/.pi/skills/grill-me/SKILL.md +2 -1
- package/.pi/skills/grill-with-docs/SKILL.md +2 -1
- package/.pi/skills/guard-git/SKILL.md +1 -0
- package/.pi/skills/hook-commits/SKILL.md +1 -0
- package/.pi/skills/inspect-quality/SKILL.md +2 -1
- package/.pi/skills/investigate-bug/SKILL.md +2 -1
- package/.pi/skills/kickoff-branch/SKILL.md +2 -1
- package/.pi/skills/map-codebase/SKILL.md +2 -1
- package/.pi/skills/migrate-spec/SKILL.md +1 -0
- package/.pi/skills/model-domain/SKILL.md +1 -0
- package/.pi/skills/orchestrate-project/SKILL.md +1 -0
- package/.pi/skills/organize-workspace/SKILL.md +2 -1
- package/.pi/skills/plan-refactor/SKILL.md +1 -0
- package/.pi/skills/plan-release/SKILL.md +2 -1
- package/.pi/skills/plan-work/SKILL.md +2 -1
- package/.pi/skills/release-branch/SKILL.md +2 -1
- package/.pi/skills/request-review/SKILL.md +1 -0
- package/.pi/skills/research-first/SKILL.md +2 -1
- package/.pi/skills/reset-baseline/SKILL.md +2 -1
- package/.pi/skills/respond-review/SKILL.md +1 -0
- package/.pi/skills/run-evals/SKILL.md +2 -1
- package/.pi/skills/run-planning/SKILL.md +2 -1
- package/.pi/skills/scope-work/SKILL.md +2 -1
- package/.pi/skills/search-skills/SKILL.md +2 -1
- package/.pi/skills/seed-conventions/SKILL.md +1 -0
- package/.pi/skills/session-state/SKILL.md +1 -0
- package/.pi/skills/setup-environment/SKILL.md +2 -1
- package/.pi/skills/simulate-agents/SKILL.md +2 -1
- package/.pi/skills/slice-tasks/SKILL.md +2 -1
- package/.pi/skills/spike-prototype/SKILL.md +2 -1
- package/.pi/skills/stocktake-skills/SKILL.md +2 -1
- package/.pi/skills/survey-context/SKILL.md +1 -0
- package/.pi/skills/terse-mode/SKILL.md +2 -1
- package/.pi/skills/trace-requirement/SKILL.md +2 -1
- package/.pi/skills/using-bigpowers/SKILL.md +2 -1
- package/.pi/skills/validate-fix/SKILL.md +2 -1
- package/.pi/skills/verify-work/SKILL.md +2 -1
- package/.pi/skills/visual-dashboard/SKILL.md +1 -0
- package/.pi/skills/wire-observability/SKILL.md +1 -0
- package/.pi/skills/write-document/SKILL.md +1 -0
- package/CHANGELOG.md +14 -0
- package/SKILL-INDEX.md +34 -33
- package/dashboard/src/web/client.html +191 -249
- package/package.json +11 -2
- package/scripts/generate-reference-tables.sh +1 -1
- package/scripts/sync-skills.sh +22 -10
- package/scripts/validate-skill-yaml.py +73 -0
- package/visual-dashboard/scripts/cockpit.html +123 -16
- package/visual-dashboard/scripts/frame-template.html +181 -45
|
@@ -5,282 +5,221 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>BigPowers Dashboard</title>
|
|
7
7
|
<style>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
/* ===== GRID TOKENS ===== */
|
|
9
|
+
:root{
|
|
10
|
+
--cols:12;
|
|
11
|
+
--bl:8px;
|
|
12
|
+
--lh:24px;
|
|
13
|
+
--gutter:24px;
|
|
14
|
+
--margin:72px;
|
|
15
|
+
--pad:48px;
|
|
16
|
+
--maxw:1296px;
|
|
17
|
+
--paper:#0d1117;
|
|
18
|
+
--ink:#c9d1d9;
|
|
19
|
+
--ink-soft:#8b949e;
|
|
20
|
+
--accent:#58a6ff;
|
|
21
|
+
--accent-hover:#79c0ff;
|
|
22
|
+
--g-col:rgba(88,166,255,.075);
|
|
23
|
+
--g-edge:rgba(88,166,255,.40);
|
|
24
|
+
--g-base:rgba(0,150,140,.34);
|
|
25
|
+
--g-base-min:rgba(0,150,140,.12);
|
|
26
|
+
}
|
|
27
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
13
28
|
|
|
14
29
|
body {
|
|
15
|
-
background:
|
|
16
|
-
color:
|
|
30
|
+
background: var(--paper);
|
|
31
|
+
color: var(--ink);
|
|
17
32
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
18
33
|
font-size: 12px;
|
|
19
|
-
line-height:
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
line-height: var(--lh);
|
|
35
|
+
-webkit-font-smoothing: antialiased;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* ---- scaffold ---- */
|
|
39
|
+
.spread{position:relative;width:100%;}
|
|
40
|
+
.wrap{position:relative;max-width:var(--maxw);margin:0 auto;padding:var(--pad) var(--margin);}
|
|
41
|
+
.grid{display:grid;grid-template-columns:repeat(var(--cols),1fr);
|
|
42
|
+
column-gap:var(--gutter);row-gap:var(--lh);}
|
|
43
|
+
.band{grid-column:1 / -1;display:grid;grid-template-columns:subgrid;
|
|
44
|
+
column-gap:var(--gutter);row-gap:var(--lh);align-items:start;}
|
|
45
|
+
@supports not (grid-template-columns:subgrid){
|
|
46
|
+
.band{grid-template-columns:repeat(var(--cols),1fr);}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* ---- toggle & guides ---- */
|
|
50
|
+
.guides{position:absolute;inset:0;pointer-events:none;z-index:60;opacity:0;
|
|
51
|
+
transition:opacity .26s ease;}
|
|
52
|
+
body.grid-on .guides{opacity:1;}
|
|
53
|
+
.guides .cols{position:absolute;top:0;bottom:0;left:var(--margin);right:var(--margin);
|
|
54
|
+
display:grid;grid-template-columns:repeat(var(--cols),1fr);column-gap:var(--gutter);}
|
|
55
|
+
.guides .col{background:var(--g-col);
|
|
56
|
+
box-shadow:inset 1px 0 0 var(--g-edge),inset -1px 0 0 var(--g-edge);position:relative;}
|
|
57
|
+
.guides .col span{position:absolute;top:32px;left:0;right:0;text-align:center;
|
|
58
|
+
font-family:"Space Mono",monospace;font-size:10px;line-height:1;color:var(--accent);}
|
|
59
|
+
.guides .rows{position:absolute;left:var(--margin);right:var(--margin);top:0;bottom:0;
|
|
60
|
+
background-image:
|
|
61
|
+
repeating-linear-gradient(to bottom,var(--g-base) 0 1px,transparent 1px var(--lh)),
|
|
62
|
+
repeating-linear-gradient(to bottom,var(--g-base-min) 0 1px,transparent 1px var(--bl));}
|
|
63
|
+
.guides .mline{position:absolute;top:0;bottom:0;width:1px;background:var(--g-edge);}
|
|
64
|
+
.guides .mline.l{left:var(--margin);} .guides .mline.r{right:var(--margin);}
|
|
65
|
+
|
|
66
|
+
.toggle{position:fixed;top:18px;right:18px;z-index:200;display:flex;align-items:center;gap:10px;
|
|
67
|
+
background:var(--ink);color:var(--paper);border:none;cursor:pointer;font-family:"Space Mono",monospace;
|
|
68
|
+
font-size:12px;letter-spacing:.14em;text-transform:uppercase;padding:11px 14px;}
|
|
69
|
+
.toggle .dot{width:9px;height:9px;border-radius:50%;background:var(--ink-soft);}
|
|
70
|
+
body.grid-on .toggle{background:var(--accent);} body.grid-on .toggle .dot{background:var(--paper);}
|
|
71
|
+
|
|
72
|
+
/* ===== COMPONENT STYLES ===== */
|
|
28
73
|
h1 {
|
|
29
74
|
font-size: 20px;
|
|
30
|
-
|
|
31
|
-
|
|
75
|
+
line-height: calc(var(--lh) * 2);
|
|
76
|
+
margin-bottom: var(--lh);
|
|
77
|
+
color: var(--accent);
|
|
32
78
|
border-bottom: 2px solid #30363d;
|
|
33
|
-
padding-bottom:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
.grid {
|
|
37
|
-
display: grid;
|
|
38
|
-
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
|
39
|
-
gap: 16px;
|
|
40
|
-
margin-bottom: 16px;
|
|
79
|
+
padding-bottom: calc(var(--lh) - 2px);
|
|
80
|
+
grid-column: 1 / -1;
|
|
41
81
|
}
|
|
42
82
|
|
|
43
83
|
.panel {
|
|
44
84
|
background: #161b22;
|
|
45
85
|
border: 1px solid #30363d;
|
|
46
86
|
border-radius: 6px;
|
|
47
|
-
padding:
|
|
87
|
+
padding: calc(var(--lh) - 1px) 23px; /* account for border */
|
|
48
88
|
}
|
|
49
89
|
|
|
50
90
|
.panel h2 {
|
|
51
91
|
font-size: 14px;
|
|
52
|
-
|
|
53
|
-
|
|
92
|
+
line-height: var(--lh);
|
|
93
|
+
margin-bottom: var(--lh);
|
|
94
|
+
color: var(--accent-hover);
|
|
54
95
|
border-bottom: 1px solid #30363d;
|
|
55
|
-
padding-bottom:
|
|
96
|
+
padding-bottom: calc(var(--lh) - 1px);
|
|
56
97
|
}
|
|
57
98
|
|
|
99
|
+
/* Keep all internal paddings/margins as multiples of --bl or --lh */
|
|
58
100
|
.metric-row {
|
|
59
101
|
display: flex;
|
|
60
102
|
justify-content: space-between;
|
|
61
|
-
padding:
|
|
103
|
+
padding: calc(var(--bl) - 1px) 0 var(--bl);
|
|
62
104
|
border-bottom: 1px solid #21262d;
|
|
105
|
+
line-height: var(--lh);
|
|
63
106
|
}
|
|
107
|
+
.metric-row:last-child { border-bottom: none; }
|
|
108
|
+
.metric-label { color: var(--ink-soft); }
|
|
109
|
+
.metric-value { color: var(--accent-hover); font-weight: bold; }
|
|
64
110
|
|
|
65
|
-
.
|
|
66
|
-
border-bottom: none;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.metric-label {
|
|
70
|
-
color: #8b949e;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.metric-value {
|
|
74
|
-
color: #79c0ff;
|
|
75
|
-
font-weight: bold;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.step-container {
|
|
79
|
-
display: flex;
|
|
80
|
-
gap: 8px;
|
|
81
|
-
flex-wrap: wrap;
|
|
82
|
-
}
|
|
83
|
-
|
|
111
|
+
.step-container { display: flex; gap: var(--bl); flex-wrap: wrap; }
|
|
84
112
|
.step {
|
|
85
|
-
flex: 1;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
border: 1px solid #30363d;
|
|
90
|
-
border-radius: 4px;
|
|
91
|
-
text-align: center;
|
|
92
|
-
font-size: 10px;
|
|
93
|
-
color: #8b949e;
|
|
113
|
+
flex: 1; min-width: 80px;
|
|
114
|
+
padding: calc(var(--bl) - 1px) calc(var(--bl) - 1px);
|
|
115
|
+
background: #21262d; border: 1px solid #30363d; border-radius: 4px;
|
|
116
|
+
text-align: center; font-size: 10px; line-height: 16px; color: var(--ink-soft);
|
|
94
117
|
transition: all 0.2s ease;
|
|
95
118
|
}
|
|
96
|
-
|
|
97
119
|
.step.active {
|
|
98
|
-
background: #238636;
|
|
99
|
-
border-color: #2ea043;
|
|
100
|
-
color: #aff5b4;
|
|
101
|
-
font-weight: bold;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.step-label {
|
|
105
|
-
display: block;
|
|
106
|
-
margin-bottom: 4px;
|
|
107
|
-
word-break: break-word;
|
|
120
|
+
background: #238636; border-color: #2ea043; color: #aff5b4; font-weight: bold;
|
|
108
121
|
}
|
|
122
|
+
.step-label { display: block; word-break: break-word; }
|
|
109
123
|
|
|
110
|
-
.state-pairs {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.state-pair {
|
|
117
|
-
display: flex;
|
|
118
|
-
flex-direction: column;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.state-key {
|
|
122
|
-
color: #8b949e;
|
|
123
|
-
font-size: 11px;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.state-value {
|
|
127
|
-
color: #79c0ff;
|
|
128
|
-
word-break: break-all;
|
|
129
|
-
margin-top: 2px;
|
|
130
|
-
}
|
|
124
|
+
.state-pairs { display: flex; flex-direction: column; gap: var(--bl); }
|
|
125
|
+
.state-pair { display: flex; flex-direction: column; line-height: 16px; }
|
|
126
|
+
.state-key { color: var(--ink-soft); font-size: 11px; }
|
|
127
|
+
.state-value { color: var(--accent-hover); word-break: break-all; margin-top: 0; }
|
|
131
128
|
|
|
132
129
|
.ledger-row {
|
|
133
|
-
padding:
|
|
134
|
-
border-bottom: 1px solid #21262d;
|
|
135
|
-
|
|
136
|
-
justify-content: space-between;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.ledger-row:last-child {
|
|
140
|
-
border-bottom: none;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.ledger-id {
|
|
144
|
-
color: #8b949e;
|
|
145
|
-
min-width: 60px;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
.ledger-value {
|
|
149
|
-
color: #79c0ff;
|
|
150
|
-
font-weight: bold;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.ledger-meta {
|
|
154
|
-
color: #6e7681;
|
|
155
|
-
font-size: 10px;
|
|
156
|
-
margin-top: 2px;
|
|
130
|
+
padding: calc(var(--bl) - 1px) 0 var(--bl);
|
|
131
|
+
border-bottom: 1px solid #21262d; display: flex; justify-content: space-between;
|
|
132
|
+
line-height: 16px;
|
|
157
133
|
}
|
|
134
|
+
.ledger-row:last-child { border-bottom: none; }
|
|
135
|
+
.ledger-id { color: var(--ink-soft); min-width: 60px; }
|
|
136
|
+
.ledger-value { color: var(--accent-hover); font-weight: bold; }
|
|
137
|
+
.ledger-meta { color: #6e7681; font-size: 10px; margin-top: 0; }
|
|
158
138
|
|
|
159
139
|
.epic-item {
|
|
160
|
-
padding:
|
|
161
|
-
background: #21262d;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
border-radius: 2px;
|
|
140
|
+
padding: calc(var(--bl) - 1px) calc(var(--bl) - 1px);
|
|
141
|
+
background: #21262d; border-left: 3px solid #30363d;
|
|
142
|
+
margin-bottom: var(--bl); border-radius: 2px;
|
|
143
|
+
line-height: 16px;
|
|
165
144
|
}
|
|
145
|
+
.epic-title { color: var(--accent-hover); font-weight: bold; margin-bottom: 0; }
|
|
146
|
+
.epic-stories { margin-left: var(--bl); color: var(--ink-soft); font-size: 11px; }
|
|
166
147
|
|
|
167
|
-
.
|
|
168
|
-
color: #79c0ff;
|
|
169
|
-
font-weight: bold;
|
|
170
|
-
margin-bottom: 4px;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.epic-stories {
|
|
174
|
-
margin-left: 8px;
|
|
175
|
-
color: #8b949e;
|
|
176
|
-
font-size: 11px;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
.status-badge {
|
|
180
|
-
display: inline-block;
|
|
181
|
-
padding: 2px 6px;
|
|
182
|
-
background: #21262d;
|
|
183
|
-
border: 1px solid #30363d;
|
|
184
|
-
border-radius: 3px;
|
|
185
|
-
font-size: 10px;
|
|
186
|
-
color: #8b949e;
|
|
187
|
-
margin-right: 4px;
|
|
188
|
-
margin-bottom: 2px;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.status-active {
|
|
192
|
-
background: #238636;
|
|
193
|
-
border-color: #2ea043;
|
|
194
|
-
color: #aff5b4;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.status-complete {
|
|
198
|
-
background: #1a414b;
|
|
199
|
-
border-color: #238636;
|
|
200
|
-
color: #7ee787;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.empty {
|
|
204
|
-
color: #6e7681;
|
|
205
|
-
font-style: italic;
|
|
206
|
-
}
|
|
148
|
+
.empty { color: #6e7681; font-style: italic; }
|
|
207
149
|
|
|
208
150
|
.connection-status {
|
|
209
|
-
position: fixed;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
background: #238636;
|
|
214
|
-
color: #aff5b4;
|
|
215
|
-
border-radius: 4px;
|
|
216
|
-
font-size: 11px;
|
|
217
|
-
border: 1px solid #2ea043;
|
|
151
|
+
position: fixed; bottom: 16px; right: 16px;
|
|
152
|
+
padding: 7px 11px; /* 16px tall total inner approx */
|
|
153
|
+
background: #238636; color: #aff5b4; border-radius: 4px;
|
|
154
|
+
font-size: 11px; border: 1px solid #2ea043; line-height: 16px;
|
|
218
155
|
}
|
|
219
|
-
|
|
220
156
|
.connection-status.disconnected {
|
|
221
|
-
background: #da3633;
|
|
222
|
-
border-color: #f85149;
|
|
223
|
-
color: #f5a8a8;
|
|
157
|
+
background: #da3633; border-color: #f85149; color: #f5a8a8;
|
|
224
158
|
}
|
|
225
159
|
</style>
|
|
226
160
|
</head>
|
|
227
161
|
<body>
|
|
228
|
-
<div class="
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
<div class="
|
|
236
|
-
|
|
162
|
+
<div class="spread">
|
|
163
|
+
<div class="wrap">
|
|
164
|
+
<div class="grid">
|
|
165
|
+
<div class="band">
|
|
166
|
+
<h1 class="opt-align">BigPowers Dashboard</h1>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<div class="band">
|
|
170
|
+
<!-- Pipeline Panel -->
|
|
171
|
+
<div class="panel" style="grid-column: 1 / -1;">
|
|
172
|
+
<h2>Pipeline</h2>
|
|
173
|
+
<div class="step-container" id="pipeline"></div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
237
176
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
177
|
+
<div class="band">
|
|
178
|
+
<!-- Metrics Panel -->
|
|
179
|
+
<div class="panel" style="grid-column: 1 / 4;">
|
|
180
|
+
<h2>Metrics</h2>
|
|
181
|
+
<div id="metrics"></div>
|
|
182
|
+
</div>
|
|
243
183
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
184
|
+
<!-- State Panel -->
|
|
185
|
+
<div class="panel" style="grid-column: 4 / 7;">
|
|
186
|
+
<h2>State</h2>
|
|
187
|
+
<div class="state-pairs" id="state"></div>
|
|
188
|
+
</div>
|
|
249
189
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
190
|
+
<!-- Epic Queue Panel -->
|
|
191
|
+
<div class="panel" style="grid-column: 7 / 10;">
|
|
192
|
+
<h2>Epic Queue</h2>
|
|
193
|
+
<div id="epics"></div>
|
|
194
|
+
</div>
|
|
255
195
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
196
|
+
<!-- Cycle-Time Ledger Panel -->
|
|
197
|
+
<div class="panel" style="grid-column: 10 / 13;">
|
|
198
|
+
<h2>Cycle-Time Ledger</h2>
|
|
199
|
+
<div id="ledger"></div>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
<!-- GRID GUIDES -->
|
|
203
|
+
<div class="guides" aria-hidden="true">
|
|
204
|
+
<div class="cols"></div><div class="rows"></div>
|
|
205
|
+
<div class="mline l"></div><div class="mline r"></div>
|
|
260
206
|
</div>
|
|
261
207
|
</div>
|
|
262
208
|
</div>
|
|
263
209
|
|
|
210
|
+
<button id="gridToggle" class="toggle"><span class="dot"></span> <span class="lbl">Show grid</span> <kbd>G</kbd></button>
|
|
264
211
|
<div class="connection-status" id="status">Live</div>
|
|
265
212
|
|
|
266
213
|
<script>
|
|
267
214
|
const PIPELINE_STEPS = [
|
|
268
|
-
'survey-context',
|
|
269
|
-
'
|
|
270
|
-
'kickoff-branch',
|
|
271
|
-
'develop-tdd',
|
|
272
|
-
'verify-work',
|
|
273
|
-
'audit-code',
|
|
274
|
-
'commit-message',
|
|
275
|
-
'release-branch'
|
|
215
|
+
'survey-context', 'plan-work', 'kickoff-branch', 'develop-tdd',
|
|
216
|
+
'verify-work', 'audit-code', 'commit-message', 'release-branch'
|
|
276
217
|
];
|
|
277
|
-
|
|
278
218
|
let eventSource = null;
|
|
279
219
|
let pollInterval = null;
|
|
280
220
|
|
|
281
221
|
function render(data) {
|
|
282
222
|
if (!data) return;
|
|
283
|
-
|
|
284
223
|
renderPipeline(data);
|
|
285
224
|
renderMetrics(data);
|
|
286
225
|
renderState(data);
|
|
@@ -292,7 +231,6 @@
|
|
|
292
231
|
const container = document.getElementById('pipeline');
|
|
293
232
|
const activeFlow = data.state?.activeFlow;
|
|
294
233
|
const activeIndex = activeFlow ? PIPELINE_STEPS.indexOf(activeFlow) : -1;
|
|
295
|
-
|
|
296
234
|
container.innerHTML = PIPELINE_STEPS.map((step, idx) => {
|
|
297
235
|
const isActive = idx === activeIndex;
|
|
298
236
|
const className = isActive ? 'step active' : 'step';
|
|
@@ -308,32 +246,17 @@
|
|
|
308
246
|
|
|
309
247
|
let html = '';
|
|
310
248
|
if (metrics) {
|
|
311
|
-
html += `<div class="metric-row">
|
|
312
|
-
|
|
313
|
-
<span class="metric-value">${metrics.totalBcps}</span>
|
|
314
|
-
</div>`;
|
|
315
|
-
html += `<div class="metric-row">
|
|
316
|
-
<span class="metric-label">Avg BCP/Hour</span>
|
|
317
|
-
<span class="metric-value">${metrics.avgBcpPerHour.toFixed(2)}</span>
|
|
318
|
-
</div>`;
|
|
249
|
+
html += `<div class="metric-row"><span class="metric-label">Total BCPs</span><span class="metric-value">${metrics.totalBcps}</span></div>`;
|
|
250
|
+
html += `<div class="metric-row"><span class="metric-label">Avg BCP/Hour</span><span class="metric-value">${metrics.avgBcpPerHour.toFixed(2)}</span></div>`;
|
|
319
251
|
}
|
|
320
252
|
if (velocity) {
|
|
321
|
-
html += `<div class="metric-row">
|
|
322
|
-
<span class="metric-label">Current Velocity</span>
|
|
323
|
-
<span class="metric-value">${velocity.avgBcpPerHour.toFixed(2)} BCP/h</span>
|
|
324
|
-
</div>`;
|
|
253
|
+
html += `<div class="metric-row"><span class="metric-label">Current Velocity</span><span class="metric-value">${velocity.avgBcpPerHour.toFixed(2)} BCP/h</span></div>`;
|
|
325
254
|
}
|
|
326
255
|
if (data.state?.release?.version) {
|
|
327
|
-
html += `<div class="metric-row">
|
|
328
|
-
<span class="metric-label">Version</span>
|
|
329
|
-
<span class="metric-value">${data.state.release.version}</span>
|
|
330
|
-
</div>`;
|
|
256
|
+
html += `<div class="metric-row"><span class="metric-label">Version</span><span class="metric-value">${data.state.release.version}</span></div>`;
|
|
331
257
|
}
|
|
332
258
|
if (timestamp) {
|
|
333
|
-
html += `<div class="metric-row">
|
|
334
|
-
<span class="metric-label">Updated</span>
|
|
335
|
-
<span class="metric-value" style="font-size: 10px;">${new Date(timestamp).toLocaleTimeString()}</span>
|
|
336
|
-
</div>`;
|
|
259
|
+
html += `<div class="metric-row"><span class="metric-label">Updated</span><span class="metric-value" style="font-size: 10px;">${new Date(timestamp).toLocaleTimeString()}</span></div>`;
|
|
337
260
|
}
|
|
338
261
|
container.innerHTML = html || '<p class="empty">No metrics available</p>';
|
|
339
262
|
}
|
|
@@ -341,41 +264,32 @@
|
|
|
341
264
|
function renderState(data) {
|
|
342
265
|
const container = document.getElementById('state');
|
|
343
266
|
const state = data.state || {};
|
|
344
|
-
|
|
345
267
|
const pairs = [
|
|
346
268
|
{ key: 'Active Flow', value: state.activeFlow },
|
|
347
269
|
{ key: 'Active Epic', value: state.activeEpic },
|
|
348
270
|
{ key: 'Active Story', value: state.activeStory },
|
|
349
271
|
{ key: 'Git Branch', value: state.gitBranch }
|
|
350
272
|
];
|
|
351
|
-
|
|
352
273
|
container.innerHTML = pairs.map(pair => {
|
|
353
274
|
const val = pair.value || '(none)';
|
|
354
|
-
return
|
|
355
|
-
<div class="state-pair">
|
|
356
|
-
<span class="state-key">${pair.key}</span>
|
|
357
|
-
<span class="state-value">${val}</span>
|
|
358
|
-
</div>
|
|
359
|
-
`;
|
|
275
|
+
return `<div class="state-pair"><span class="state-key">${pair.key}</span><span class="state-value">${val}</span></div>`;
|
|
360
276
|
}).join('');
|
|
361
277
|
}
|
|
362
278
|
|
|
363
279
|
function renderEpics(data) {
|
|
364
280
|
const container = document.getElementById('epics');
|
|
365
281
|
const epics = data.epics || [];
|
|
366
|
-
|
|
367
282
|
if (epics.length === 0) {
|
|
368
283
|
container.innerHTML = '<p class="empty">No epics available</p>';
|
|
369
284
|
return;
|
|
370
285
|
}
|
|
371
|
-
|
|
372
286
|
container.innerHTML = epics.map(epic => {
|
|
373
287
|
const stories = epic.stories || [];
|
|
374
288
|
const storyCount = stories.length;
|
|
375
289
|
return `
|
|
376
290
|
<div class="epic-item">
|
|
377
291
|
<div class="epic-title">${epic.id || 'Unknown'}</div>
|
|
378
|
-
<div style="color:
|
|
292
|
+
<div style="color: var(--ink-soft); font-size: 11px; margin-bottom: 0;">${epic.title || 'Untitled'}</div>
|
|
379
293
|
<div class="epic-stories">${storyCount} stories</div>
|
|
380
294
|
</div>
|
|
381
295
|
`;
|
|
@@ -385,12 +299,10 @@
|
|
|
385
299
|
function renderLedger(data) {
|
|
386
300
|
const container = document.getElementById('ledger');
|
|
387
301
|
const cycleTimes = data.cycleTimes || [];
|
|
388
|
-
|
|
389
302
|
if (cycleTimes.length === 0) {
|
|
390
303
|
container.innerHTML = '<p class="empty">No cycle-time data available</p>';
|
|
391
304
|
return;
|
|
392
305
|
}
|
|
393
|
-
|
|
394
306
|
const recentRows = cycleTimes.slice(-8);
|
|
395
307
|
container.innerHTML = recentRows.map(row => {
|
|
396
308
|
const end = row.end ? new Date(row.end).toLocaleDateString() : '(active)';
|
|
@@ -420,7 +332,6 @@
|
|
|
420
332
|
function startEventSource() {
|
|
421
333
|
eventSource = new EventSource('/events');
|
|
422
334
|
setConnectionStatus(true);
|
|
423
|
-
|
|
424
335
|
eventSource.onmessage = (event) => {
|
|
425
336
|
try {
|
|
426
337
|
const data = JSON.parse(event.data);
|
|
@@ -429,7 +340,6 @@
|
|
|
429
340
|
console.error('Failed to parse SSE data:', err);
|
|
430
341
|
}
|
|
431
342
|
};
|
|
432
|
-
|
|
433
343
|
eventSource.onerror = (err) => {
|
|
434
344
|
console.warn('SSE connection lost, falling back to polling');
|
|
435
345
|
eventSource.close();
|
|
@@ -440,7 +350,6 @@
|
|
|
440
350
|
|
|
441
351
|
function startPolling() {
|
|
442
352
|
if (pollInterval) return;
|
|
443
|
-
|
|
444
353
|
pollInterval = setInterval(() => {
|
|
445
354
|
fetch('/api/state')
|
|
446
355
|
.then(res => res.json())
|
|
@@ -459,7 +368,6 @@
|
|
|
459
368
|
}
|
|
460
369
|
}
|
|
461
370
|
|
|
462
|
-
// Initial load
|
|
463
371
|
window.addEventListener('load', () => {
|
|
464
372
|
fetch('/api/state')
|
|
465
373
|
.then(res => res.json())
|
|
@@ -472,6 +380,40 @@
|
|
|
472
380
|
startPolling();
|
|
473
381
|
});
|
|
474
382
|
});
|
|
383
|
+
|
|
384
|
+
/* ===== GRID SCRIPT ===== */
|
|
385
|
+
var btn=document.getElementById('gridToggle');
|
|
386
|
+
function setGrid(on){document.body.classList.toggle('grid-on',on);
|
|
387
|
+
if(btn){btn.setAttribute('aria-pressed',on?'true':'false');
|
|
388
|
+
var l=btn.querySelector('.lbl'); if(l) l.textContent=on?'Hide grid':'Show grid';}}
|
|
389
|
+
if(btn) btn.addEventListener('click',function(){setGrid(!document.body.classList.contains('grid-on'));});
|
|
390
|
+
document.addEventListener('keydown',function(e){
|
|
391
|
+
if((e.key==='g'||e.key==='G')&&!e.metaKey&&!e.ctrlKey&&!e.altKey){
|
|
392
|
+
setGrid(!document.body.classList.contains('grid-on'));}});
|
|
393
|
+
|
|
394
|
+
document.querySelectorAll('.guides .cols').forEach(function(h){
|
|
395
|
+
var n=getComputedStyle(document.documentElement).getPropertyValue('--cols').trim()||'12';
|
|
396
|
+
for(var i=1;i<=parseInt(n,10);i++){var c=document.createElement('div');c.className='col';
|
|
397
|
+
var s=document.createElement('span');s.textContent=i;c.appendChild(s);h.appendChild(c);}});
|
|
398
|
+
|
|
399
|
+
(function(){
|
|
400
|
+
var cvs=document.createElement('canvas'),ctx=cvs.getContext('2d');
|
|
401
|
+
var sel='.opt-align';
|
|
402
|
+
function align(){
|
|
403
|
+
document.querySelectorAll(sel).forEach(function(el){
|
|
404
|
+
el.style.marginLeft='0px';
|
|
405
|
+
var cs=getComputedStyle(el),ch=(el.textContent||'').trim().charAt(0); if(!ch) return;
|
|
406
|
+
if(cs.textTransform==='uppercase') ch=ch.toUpperCase();
|
|
407
|
+
ctx.font=cs.fontStyle+' '+cs.fontWeight+' '+cs.fontSize+' '+cs.fontFamily;
|
|
408
|
+
ctx.textAlign='left';
|
|
409
|
+
var abl=ctx.measureText(ch).actualBoundingBoxLeft;
|
|
410
|
+
if(isFinite(abl)) el.style.marginLeft=abl.toFixed(2)+'px';
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
if(document.fonts&&document.fonts.ready){document.fonts.ready.then(align);}
|
|
414
|
+
align();
|
|
415
|
+
var t;window.addEventListener('resize',function(){clearTimeout(t);t=setTimeout(align,120);});
|
|
416
|
+
})();
|
|
475
417
|
</script>
|
|
476
418
|
</body>
|
|
477
419
|
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bigpowers",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "61 agent skills for spec-driven, test-first software development by solo developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,8 +22,17 @@
|
|
|
22
22
|
"claude",
|
|
23
23
|
"development",
|
|
24
24
|
"spec-driven",
|
|
25
|
-
"test-first"
|
|
25
|
+
"test-first",
|
|
26
|
+
"pi-package"
|
|
26
27
|
],
|
|
28
|
+
"pi": {
|
|
29
|
+
"skills": [
|
|
30
|
+
"./.pi/skills"
|
|
31
|
+
],
|
|
32
|
+
"prompts": [
|
|
33
|
+
"./.pi/prompts"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
27
36
|
"author": "Daniel",
|
|
28
37
|
"license": "MIT",
|
|
29
38
|
"homepage": "https://github.com/danielvm-git/bigpowers#readme",
|
|
@@ -16,7 +16,7 @@ while IFS= read -r line; do
|
|
|
16
16
|
model_raw="${line##*model: }"
|
|
17
17
|
model="${model_raw// /}"
|
|
18
18
|
ROWS+=("$skill_dir $model")
|
|
19
|
-
done < <(grep -r "^model:" */SKILL.md |
|
|
19
|
+
done < <(grep -r "^model:" */SKILL.md | sort)
|
|
20
20
|
|
|
21
21
|
TOTAL=${#ROWS[@]}
|
|
22
22
|
|