@x0rium/devkit-cli 0.4.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.
- package/dist/advance.d.ts +9 -0
- package/dist/advance.d.ts.map +1 -0
- package/dist/advance.js +47 -0
- package/dist/advance.js.map +1 -0
- package/dist/constitution.d.ts +16 -0
- package/dist/constitution.d.ts.map +1 -0
- package/dist/constitution.js +186 -0
- package/dist/constitution.js.map +1 -0
- package/dist/coverage.d.ts +18 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +167 -0
- package/dist/coverage.js.map +1 -0
- package/dist/dashboard.d.ts +2 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +380 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/detector.d.ts +3 -0
- package/dist/detector.d.ts.map +1 -0
- package/dist/detector.js +45 -0
- package/dist/detector.js.map +1 -0
- package/dist/escalate.d.ts +11 -0
- package/dist/escalate.d.ts.map +1 -0
- package/dist/escalate.js +133 -0
- package/dist/escalate.js.map +1 -0
- package/dist/gate.d.ts +15 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +244 -0
- package/dist/gate.js.map +1 -0
- package/dist/impact.d.ts +17 -0
- package/dist/impact.d.ts.map +1 -0
- package/dist/impact.js +192 -0
- package/dist/impact.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +494 -0
- package/dist/index.js.map +1 -0
- package/dist/investigate.d.ts +21 -0
- package/dist/investigate.d.ts.map +1 -0
- package/dist/investigate.js +200 -0
- package/dist/investigate.js.map +1 -0
- package/dist/rfc.d.ts +21 -0
- package/dist/rfc.d.ts.map +1 -0
- package/dist/rfc.js +152 -0
- package/dist/rfc.js.map +1 -0
- package/dist/scaffold.d.ts +7 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +54 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/schemas.d.ts +11 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +103 -0
- package/dist/schemas.js.map +1 -0
- package/dist/status.d.ts +13 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +112 -0
- package/dist/status.js.map +1 -0
- package/dist/validator.d.ts +16 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +185 -0
- package/dist/validator.js.map +1 -0
- package/dist/watch.d.ts +2 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +48 -0
- package/dist/watch.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { getStatus } from './status.js';
|
|
3
|
+
import { validateArtifacts } from './validator.js';
|
|
4
|
+
import { analyzeCoverage } from './coverage.js';
|
|
5
|
+
import { listRfcs } from './rfc.js';
|
|
6
|
+
import { listInvestigations } from './investigate.js';
|
|
7
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
export function startDashboard(cwd, port) {
|
|
10
|
+
const server = createServer((req, res) => {
|
|
11
|
+
if (req.url === '/api/data') {
|
|
12
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
13
|
+
res.end(JSON.stringify(collectData(cwd)));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
17
|
+
res.end(generateHtml());
|
|
18
|
+
});
|
|
19
|
+
server.listen(port, () => {
|
|
20
|
+
console.log(`\n🌐 Dashboard running at http://localhost:${port}\n`);
|
|
21
|
+
console.log(` Press Ctrl+C to stop.\n`);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function collectData(cwd) {
|
|
25
|
+
const status = getStatus(cwd);
|
|
26
|
+
const validation = validateArtifacts(cwd);
|
|
27
|
+
const coverage = analyzeCoverage(cwd);
|
|
28
|
+
const rfcs = listRfcs(cwd);
|
|
29
|
+
const investigations = listInvestigations(cwd);
|
|
30
|
+
// Count escalations
|
|
31
|
+
const escDir = join(cwd, '.devkit', 'qa', 'escalations');
|
|
32
|
+
let escalations = [];
|
|
33
|
+
if (existsSync(escDir)) {
|
|
34
|
+
escalations = readdirSync(escDir)
|
|
35
|
+
.filter(f => f.startsWith('ESC-'))
|
|
36
|
+
.map(f => {
|
|
37
|
+
const content = readFileSync(join(escDir, f), 'utf-8');
|
|
38
|
+
const levelMatch = content.match(/^ESCALATED_TO:\s*(.+)/m);
|
|
39
|
+
const statusMatch = content.match(/^STATUS:\s*(.+)/m);
|
|
40
|
+
return {
|
|
41
|
+
id: f.replace('.md', ''),
|
|
42
|
+
level: levelMatch?.[1]?.trim() ?? 'unknown',
|
|
43
|
+
status: statusMatch?.[1]?.trim() ?? 'unknown',
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
status,
|
|
49
|
+
validation: {
|
|
50
|
+
total: validation.filesChecked,
|
|
51
|
+
errors: validation.errors.length,
|
|
52
|
+
errorList: validation.errors.slice(0, 10),
|
|
53
|
+
},
|
|
54
|
+
coverage: {
|
|
55
|
+
percentage: coverage.percentage,
|
|
56
|
+
covered: coverage.covered,
|
|
57
|
+
partial: coverage.partial,
|
|
58
|
+
uncovered: coverage.uncovered,
|
|
59
|
+
total: coverage.totalInvariants,
|
|
60
|
+
entries: coverage.entries,
|
|
61
|
+
},
|
|
62
|
+
rfcs,
|
|
63
|
+
investigations,
|
|
64
|
+
escalations,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function generateHtml() {
|
|
68
|
+
return `<!DOCTYPE html>
|
|
69
|
+
<html lang="en">
|
|
70
|
+
<head>
|
|
71
|
+
<meta charset="UTF-8">
|
|
72
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
73
|
+
<title>DevKit Dashboard</title>
|
|
74
|
+
<style>
|
|
75
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
|
76
|
+
|
|
77
|
+
:root {
|
|
78
|
+
--bg: #0a0a0f;
|
|
79
|
+
--surface: #12121a;
|
|
80
|
+
--surface2: #1a1a25;
|
|
81
|
+
--border: #2a2a3a;
|
|
82
|
+
--text: #e0e0e8;
|
|
83
|
+
--text-dim: #8888a0;
|
|
84
|
+
--accent: #6c5ce7;
|
|
85
|
+
--accent-glow: rgba(108, 92, 231, 0.15);
|
|
86
|
+
--green: #00cc88;
|
|
87
|
+
--yellow: #ffbe0b;
|
|
88
|
+
--red: #ff5555;
|
|
89
|
+
--blue: #4fc3f7;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
93
|
+
|
|
94
|
+
body {
|
|
95
|
+
font-family: 'Inter', -apple-system, sans-serif;
|
|
96
|
+
background: var(--bg);
|
|
97
|
+
color: var(--text);
|
|
98
|
+
min-height: 100vh;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.header {
|
|
102
|
+
padding: 28px 40px;
|
|
103
|
+
border-bottom: 1px solid var(--border);
|
|
104
|
+
display: flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
gap: 16px;
|
|
107
|
+
background: linear-gradient(135deg, var(--surface) 0%, rgba(108, 92, 231, 0.05) 100%);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.header h1 {
|
|
111
|
+
font-size: 24px;
|
|
112
|
+
font-weight: 600;
|
|
113
|
+
background: linear-gradient(135deg, #6c5ce7, #a29bfe);
|
|
114
|
+
-webkit-background-clip: text;
|
|
115
|
+
-webkit-text-fill-color: transparent;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.header .version {
|
|
119
|
+
background: var(--accent-glow);
|
|
120
|
+
border: 1px solid rgba(108, 92, 231, 0.3);
|
|
121
|
+
padding: 2px 10px;
|
|
122
|
+
border-radius: 12px;
|
|
123
|
+
font-size: 12px;
|
|
124
|
+
color: #a29bfe;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.header .refresh {
|
|
128
|
+
margin-left: auto;
|
|
129
|
+
font-size: 13px;
|
|
130
|
+
color: var(--text-dim);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.grid {
|
|
134
|
+
display: grid;
|
|
135
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
136
|
+
gap: 20px;
|
|
137
|
+
padding: 28px 40px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.card {
|
|
141
|
+
background: var(--surface);
|
|
142
|
+
border: 1px solid var(--border);
|
|
143
|
+
border-radius: 12px;
|
|
144
|
+
padding: 24px;
|
|
145
|
+
transition: border-color 0.2s;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.card:hover { border-color: rgba(108, 92, 231, 0.4); }
|
|
149
|
+
|
|
150
|
+
.card-title {
|
|
151
|
+
font-size: 11px;
|
|
152
|
+
text-transform: uppercase;
|
|
153
|
+
letter-spacing: 1.5px;
|
|
154
|
+
color: var(--text-dim);
|
|
155
|
+
margin-bottom: 16px;
|
|
156
|
+
font-weight: 600;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.card.wide { grid-column: span 2; }
|
|
160
|
+
.card.full { grid-column: span 3; }
|
|
161
|
+
|
|
162
|
+
/* Phase Progress */
|
|
163
|
+
.phases { display: flex; gap: 8px; align-items: center; }
|
|
164
|
+
.phase {
|
|
165
|
+
flex: 1;
|
|
166
|
+
text-align: center;
|
|
167
|
+
padding: 12px 8px;
|
|
168
|
+
border-radius: 8px;
|
|
169
|
+
font-size: 12px;
|
|
170
|
+
font-weight: 500;
|
|
171
|
+
position: relative;
|
|
172
|
+
}
|
|
173
|
+
.phase.done { background: rgba(0, 204, 136, 0.1); color: var(--green); border: 1px solid rgba(0, 204, 136, 0.2); }
|
|
174
|
+
.phase.current { background: var(--accent-glow); color: #a29bfe; border: 1px solid rgba(108, 92, 231, 0.4); animation: pulse 2s infinite; }
|
|
175
|
+
.phase.pending { background: var(--surface2); color: var(--text-dim); border: 1px solid var(--border); }
|
|
176
|
+
.phase-arrow { color: var(--text-dim); font-size: 18px; }
|
|
177
|
+
|
|
178
|
+
@keyframes pulse {
|
|
179
|
+
0%, 100% { box-shadow: 0 0 0 0 rgba(108, 92, 231, 0.3); }
|
|
180
|
+
50% { box-shadow: 0 0 12px 4px rgba(108, 92, 231, 0.15); }
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Stats */
|
|
184
|
+
.stats { display: flex; gap: 24px; }
|
|
185
|
+
.stat-value { font-size: 36px; font-weight: 700; }
|
|
186
|
+
.stat-label { font-size: 12px; color: var(--text-dim); margin-top: 4px; }
|
|
187
|
+
.stat-value.green { color: var(--green); }
|
|
188
|
+
.stat-value.yellow { color: var(--yellow); }
|
|
189
|
+
.stat-value.red { color: var(--red); }
|
|
190
|
+
|
|
191
|
+
/* Coverage Bar */
|
|
192
|
+
.coverage-bar-container { margin: 12px 0; }
|
|
193
|
+
.coverage-bar {
|
|
194
|
+
height: 8px;
|
|
195
|
+
background: var(--surface2);
|
|
196
|
+
border-radius: 4px;
|
|
197
|
+
overflow: hidden;
|
|
198
|
+
}
|
|
199
|
+
.coverage-fill {
|
|
200
|
+
height: 100%;
|
|
201
|
+
border-radius: 4px;
|
|
202
|
+
transition: width 0.5s ease;
|
|
203
|
+
}
|
|
204
|
+
.coverage-pct { font-size: 32px; font-weight: 700; margin-bottom: 4px; }
|
|
205
|
+
|
|
206
|
+
/* Items list */
|
|
207
|
+
.items { display: flex; flex-direction: column; gap: 8px; }
|
|
208
|
+
.item {
|
|
209
|
+
display: flex; align-items: center; gap: 10px;
|
|
210
|
+
padding: 10px 12px;
|
|
211
|
+
background: var(--surface2);
|
|
212
|
+
border-radius: 8px;
|
|
213
|
+
font-size: 13px;
|
|
214
|
+
}
|
|
215
|
+
.item-icon { font-size: 16px; }
|
|
216
|
+
.item-id { font-weight: 600; color: var(--blue); min-width: 60px; }
|
|
217
|
+
.item-text { flex: 1; color: var(--text); }
|
|
218
|
+
.item-status {
|
|
219
|
+
padding: 2px 8px; border-radius: 10px; font-size: 11px; font-weight: 500;
|
|
220
|
+
}
|
|
221
|
+
.item-status.open { background: rgba(255, 190, 11, 0.15); color: var(--yellow); }
|
|
222
|
+
.item-status.accepted, .item-status.resolved { background: rgba(0, 204, 136, 0.15); color: var(--green); }
|
|
223
|
+
|
|
224
|
+
/* Coverage entries */
|
|
225
|
+
.cov-entry {
|
|
226
|
+
display: flex; align-items: center; gap: 10px;
|
|
227
|
+
padding: 8px 12px;
|
|
228
|
+
background: var(--surface2);
|
|
229
|
+
border-radius: 8px;
|
|
230
|
+
font-size: 13px;
|
|
231
|
+
}
|
|
232
|
+
.cov-entry.covered { border-left: 3px solid var(--green); }
|
|
233
|
+
.cov-entry.partial { border-left: 3px solid var(--yellow); }
|
|
234
|
+
.cov-entry.uncovered { border-left: 3px solid var(--red); }
|
|
235
|
+
.cov-entry .tests { color: var(--text-dim); font-size: 11px; margin-left: auto; }
|
|
236
|
+
|
|
237
|
+
/* Validation errors */
|
|
238
|
+
.error-item {
|
|
239
|
+
padding: 10px 12px;
|
|
240
|
+
background: rgba(255, 85, 85, 0.05);
|
|
241
|
+
border-left: 3px solid var(--red);
|
|
242
|
+
border-radius: 0 8px 8px 0;
|
|
243
|
+
font-size: 13px;
|
|
244
|
+
margin-bottom: 6px;
|
|
245
|
+
}
|
|
246
|
+
.error-file { color: var(--blue); font-weight: 500; }
|
|
247
|
+
.error-msg { color: var(--text); margin-top: 4px; }
|
|
248
|
+
.error-fix { color: var(--green); font-size: 12px; margin-top: 2px; }
|
|
249
|
+
|
|
250
|
+
.empty { color: var(--text-dim); font-style: italic; font-size: 13px; }
|
|
251
|
+
|
|
252
|
+
/* Escalation flow */
|
|
253
|
+
.flow { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
|
|
254
|
+
.flow-node {
|
|
255
|
+
padding: 6px 14px; border-radius: 20px; font-size: 12px; font-weight: 500;
|
|
256
|
+
}
|
|
257
|
+
.flow-node.speckit { background: rgba(79, 195, 247, 0.15); color: var(--blue); }
|
|
258
|
+
.flow-node.archkit { background: rgba(108, 92, 231, 0.15); color: #a29bfe; }
|
|
259
|
+
.flow-node.productkit { background: rgba(255, 190, 11, 0.15); color: var(--yellow); }
|
|
260
|
+
.flow-node.researchkit { background: rgba(0, 204, 136, 0.15); color: var(--green); }
|
|
261
|
+
</style>
|
|
262
|
+
</head>
|
|
263
|
+
<body>
|
|
264
|
+
<div class="header">
|
|
265
|
+
<h1>⬡ DevKit Dashboard</h1>
|
|
266
|
+
<span class="version">v0.4.0</span>
|
|
267
|
+
<span class="refresh" id="refresh-time">Loading...</span>
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<div class="grid" id="content">
|
|
271
|
+
<div class="card full" style="text-align:center; padding: 60px;">
|
|
272
|
+
<div style="font-size: 24px; margin-bottom: 12px;">⏳</div>
|
|
273
|
+
<div style="color: var(--text-dim);">Loading dashboard...</div>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
|
|
277
|
+
<script>
|
|
278
|
+
async function loadData() {
|
|
279
|
+
const res = await fetch('/api/data');
|
|
280
|
+
const data = await res.json();
|
|
281
|
+
render(data);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function render(d) {
|
|
285
|
+
const s = d.status;
|
|
286
|
+
const phases = ['research', 'product', 'arch', 'spec', 'qa'];
|
|
287
|
+
const labels = { research: 'Research', product: 'Product', arch: 'Arch', spec: 'Spec', qa: 'QA' };
|
|
288
|
+
|
|
289
|
+
// Phase statuses — phaseProgress is a Record<phase, status>
|
|
290
|
+
const phaseMap = s ? (s.phaseProgress || {}) : {};
|
|
291
|
+
|
|
292
|
+
const phaseHtml = phases.map(p => {
|
|
293
|
+
const st = phaseMap[p] || 'pending';
|
|
294
|
+
const cls = st === 'done' ? 'done' : (s && s.phase === p) ? 'current' : 'pending';
|
|
295
|
+
const icon = st === 'done' ? '✅' : (s && s.phase === p) ? '◆' : '○';
|
|
296
|
+
return '<div class="phase ' + cls + '">' + icon + ' ' + labels[p] + 'Kit</div>';
|
|
297
|
+
}).join('<span class="phase-arrow">→</span>');
|
|
298
|
+
|
|
299
|
+
// Coverage color
|
|
300
|
+
const pct = d.coverage.percentage;
|
|
301
|
+
const covColor = pct >= 80 ? 'var(--green)' : pct >= 50 ? 'var(--yellow)' : 'var(--red)';
|
|
302
|
+
|
|
303
|
+
// Coverage entries
|
|
304
|
+
const covHtml = d.coverage.entries.map(e => {
|
|
305
|
+
const tests = e.coveredBy.length > 0 ? e.coveredBy.join(', ') : 'none';
|
|
306
|
+
return '<div class="cov-entry ' + e.status + '">' +
|
|
307
|
+
'<span>' + (e.status === 'covered' ? '✅' : e.status === 'partial' ? '🟡' : '❌') + '</span>' +
|
|
308
|
+
'<span>' + e.invariant + '</span>' +
|
|
309
|
+
'<span class="tests">' + tests + '</span></div>';
|
|
310
|
+
}).join('') || '<div class="empty">No invariants found</div>';
|
|
311
|
+
|
|
312
|
+
// RFCs
|
|
313
|
+
const rfcHtml = d.rfcs.map(r => {
|
|
314
|
+
const title = r.title.replace(r.id + ': ', '');
|
|
315
|
+
return '<div class="item"><span class="item-id">' + r.id + '</span>' +
|
|
316
|
+
'<span class="item-text">' + title + '</span>' +
|
|
317
|
+
'<span class="item-status ' + r.status + '">' + r.status + '</span></div>';
|
|
318
|
+
}).join('') || '<div class="empty">No RFCs created</div>';
|
|
319
|
+
|
|
320
|
+
// Investigations
|
|
321
|
+
const invHtml = d.investigations.map(i => {
|
|
322
|
+
const title = i.title.replace(i.id + ': ', '');
|
|
323
|
+
return '<div class="item"><span class="item-id">' + i.id + '</span>' +
|
|
324
|
+
'<span class="item-text">' + title + '</span>' +
|
|
325
|
+
'<span class="item-status ' + i.status + '">' + i.status + '</span></div>';
|
|
326
|
+
}).join('') || '<div class="empty">No investigations</div>';
|
|
327
|
+
|
|
328
|
+
// Escalations
|
|
329
|
+
const escHtml = d.escalations.map(e =>
|
|
330
|
+
'<div class="item"><span class="item-id">' + e.id + '</span>' +
|
|
331
|
+
'<span class="flow-node ' + e.level + '">' + e.level + '</span>' +
|
|
332
|
+
'<span class="item-status ' + e.status + '">' + e.status + '</span></div>'
|
|
333
|
+
).join('') || '<div class="empty">No escalations</div>';
|
|
334
|
+
|
|
335
|
+
// Validation errors
|
|
336
|
+
const errHtml = d.validation.errorList.map(e =>
|
|
337
|
+
'<div class="error-item"><div class="error-file">' + e.file + ':' + e.line + '</div>' +
|
|
338
|
+
'<div class="error-msg">' + e.message + '</div>' +
|
|
339
|
+
'<div class="error-fix">Fix: ' + e.fix + '</div></div>'
|
|
340
|
+
).join('') || '<div class="empty" style="color: var(--green);">✅ All artifacts valid</div>';
|
|
341
|
+
|
|
342
|
+
document.getElementById('content').innerHTML =
|
|
343
|
+
// Row 1: Phase progress
|
|
344
|
+
'<div class="card full"><div class="card-title">Phase Progress</div><div class="phases">' + phaseHtml + '</div></div>' +
|
|
345
|
+
|
|
346
|
+
// Row 2: Stats + Coverage + Validation
|
|
347
|
+
'<div class="card"><div class="card-title">Overview</div><div class="stats">' +
|
|
348
|
+
'<div><div class="stat-value green">' + d.coverage.covered + '</div><div class="stat-label">Covered</div></div>' +
|
|
349
|
+
'<div><div class="stat-value yellow">' + d.coverage.partial + '</div><div class="stat-label">Partial</div></div>' +
|
|
350
|
+
'<div><div class="stat-value red">' + d.coverage.uncovered + '</div><div class="stat-label">Uncovered</div></div>' +
|
|
351
|
+
'</div></div>' +
|
|
352
|
+
|
|
353
|
+
'<div class="card"><div class="card-title">Coverage</div>' +
|
|
354
|
+
'<div class="coverage-pct" style="color:' + covColor + '">' + pct + '%</div>' +
|
|
355
|
+
'<div class="coverage-bar-container"><div class="coverage-bar"><div class="coverage-fill" style="width:' + pct + '%; background:' + covColor + '"></div></div></div>' +
|
|
356
|
+
'<div class="stat-label">' + d.coverage.covered + ' of ' + d.coverage.total + ' invariants fully tested</div></div>' +
|
|
357
|
+
|
|
358
|
+
'<div class="card"><div class="card-title">Validation</div>' +
|
|
359
|
+
'<div class="stat-value ' + (d.validation.errors > 0 ? 'red' : 'green') + '">' + d.validation.errors + '</div>' +
|
|
360
|
+
'<div class="stat-label">errors in ' + d.validation.total + ' artifacts</div></div>' +
|
|
361
|
+
|
|
362
|
+
// Row 3: Coverage + Errors
|
|
363
|
+
'<div class="card wide"><div class="card-title">Invariant Coverage Map</div><div class="items">' + covHtml + '</div></div>' +
|
|
364
|
+
'<div class="card"><div class="card-title">Validation Errors</div>' + errHtml + '</div>' +
|
|
365
|
+
|
|
366
|
+
// Row 4: RFCs + Investigations + Escalations
|
|
367
|
+
'<div class="card"><div class="card-title">📋 RFCs</div><div class="items">' + rfcHtml + '</div></div>' +
|
|
368
|
+
'<div class="card"><div class="card-title">🔬 Investigations</div><div class="items">' + invHtml + '</div></div>' +
|
|
369
|
+
'<div class="card"><div class="card-title">🚨 Escalations</div><div class="items">' + escHtml + '</div></div>';
|
|
370
|
+
|
|
371
|
+
document.getElementById('refresh-time').textContent = 'Last: ' + new Date().toLocaleTimeString() + ' · Auto-refresh 5s';
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
loadData();
|
|
375
|
+
setInterval(loadData, 5000);
|
|
376
|
+
</script>
|
|
377
|
+
</body>
|
|
378
|
+
</html>`;
|
|
379
|
+
}
|
|
380
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../src/detector.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC;AA6BnF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAiB5D"}
|
package/dist/detector.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readdirSync, existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const CODE_EXTENSIONS = new Set([
|
|
4
|
+
'.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs', '.java',
|
|
5
|
+
'.c', '.cpp', '.h', '.cs', '.rb', '.php', '.swift', '.kt',
|
|
6
|
+
]);
|
|
7
|
+
function hasCodeFiles(dir) {
|
|
8
|
+
try {
|
|
9
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
10
|
+
for (const entry of entries) {
|
|
11
|
+
if (entry.name.startsWith('.'))
|
|
12
|
+
continue;
|
|
13
|
+
if (entry.name === 'node_modules')
|
|
14
|
+
continue;
|
|
15
|
+
if (entry.isFile()) {
|
|
16
|
+
const ext = entry.name.substring(entry.name.lastIndexOf('.'));
|
|
17
|
+
if (CODE_EXTENSIONS.has(ext))
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (entry.isDirectory()) {
|
|
21
|
+
if (hasCodeFiles(join(dir, entry.name)))
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Permission errors, etc.
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
export function detectProjectState(cwd) {
|
|
32
|
+
const devkitDir = join(cwd, '.devkit');
|
|
33
|
+
const specifyDir = join(cwd, '.specify');
|
|
34
|
+
if (existsSync(devkitDir) && statSync(devkitDir).isDirectory()) {
|
|
35
|
+
return 'initialized';
|
|
36
|
+
}
|
|
37
|
+
if (existsSync(specifyDir) && statSync(specifyDir).isDirectory()) {
|
|
38
|
+
return 'upgrade';
|
|
39
|
+
}
|
|
40
|
+
if (hasCodeFiles(cwd)) {
|
|
41
|
+
return 'brownfield';
|
|
42
|
+
}
|
|
43
|
+
return 'greenfield';
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../src/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO;IAC1D,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK;CAC5D,CAAC,CAAC;AAEH,SAAS,YAAY,CAAC,GAAW;IAC7B,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACzC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;gBAAE,SAAS;YAE5C,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACjB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC9D,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,OAAO,IAAI,CAAC;YAC9C,CAAC;YAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACtB,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBAAE,OAAO,IAAI,CAAC;YACzD,CAAC;QACL,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,0BAA0B;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAEzC,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7D,OAAO,aAAa,CAAC;IACzB,CAAC;IAED,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/D,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,YAAY,CAAC;IACxB,CAAC;IAED,OAAO,YAAY,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type EscalationLevel = 'speckit' | 'archkit' | 'productkit' | 'researchkit';
|
|
2
|
+
export interface EscalationResult {
|
|
3
|
+
created: boolean;
|
|
4
|
+
id: string;
|
|
5
|
+
path: string;
|
|
6
|
+
level: EscalationLevel;
|
|
7
|
+
reason: string;
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function createEscalation(cwd: string, description: string, forceLevel?: EscalationLevel): EscalationResult;
|
|
11
|
+
//# sourceMappingURL=escalate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escalate.d.ts","sourceRoot":"","sources":["../src/escalate.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;AAEnF,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAuDD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAgGjH"}
|
package/dist/escalate.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { writeFileSync, existsSync, readdirSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const LEVEL_DESCRIPTIONS = {
|
|
4
|
+
speckit: 'Code bug — code doesn\'t match spec. Fix in SpecKit.',
|
|
5
|
+
archkit: 'Invariant violation — system breaks an architectural guarantee. Investigation needed.',
|
|
6
|
+
productkit: 'UX problem — system works but user experience is wrong. Product investigation needed.',
|
|
7
|
+
researchkit: 'Assumption rejected — a research assumption proved false. Research revision needed.',
|
|
8
|
+
};
|
|
9
|
+
function detectEscalationLevel(cwd, description) {
|
|
10
|
+
const lower = description.toLowerCase();
|
|
11
|
+
// Check for UX-related keywords → ProductKit
|
|
12
|
+
const uxKeywords = ['ux', 'user experience', 'usability', 'confusing', 'unintuitive',
|
|
13
|
+
'hard to use', 'awkward', 'too many', 'parameters', 'complicated', 'неудобно',
|
|
14
|
+
'непонятно', 'слишком', 'пользователь не'];
|
|
15
|
+
for (const kw of uxKeywords) {
|
|
16
|
+
if (lower.includes(kw)) {
|
|
17
|
+
return { level: 'productkit', reason: `UX issue detected ("${kw}"). Escalating to ProductKit.` };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// Check for assumption/research keywords → ResearchKit
|
|
21
|
+
const researchKeywords = ['assumption', 'assumed', 'we thought', 'turns out',
|
|
22
|
+
'wrong assumption', 'predicted', 'expected market', 'feasibility',
|
|
23
|
+
'предполагали', 'оказалось'];
|
|
24
|
+
for (const kw of researchKeywords) {
|
|
25
|
+
if (lower.includes(kw)) {
|
|
26
|
+
return { level: 'researchkit', reason: `Research assumption challenged ("${kw}"). Escalating to ResearchKit.` };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Check for invariant/architecture keywords → ArchKit
|
|
30
|
+
const archKeywords = ['invariant', 'guarantee', 'architecture', 'design flaw',
|
|
31
|
+
'fundamental', 'race condition', 'data loss', 'security', 'performance',
|
|
32
|
+
'инвариант', 'архитектур', 'гарантия'];
|
|
33
|
+
for (const kw of archKeywords) {
|
|
34
|
+
if (lower.includes(kw)) {
|
|
35
|
+
return { level: 'archkit', reason: `Architectural issue detected ("${kw}"). Escalating to ArchKit.` };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Check for bug/library keywords → ArchKit investigation
|
|
39
|
+
const bugKeywords = ['bug in', 'library', 'doesn\'t support', 'benchmark',
|
|
40
|
+
'unexpected behavior', 'limitation', 'баг', 'либа не'];
|
|
41
|
+
for (const kw of bugKeywords) {
|
|
42
|
+
if (lower.includes(kw)) {
|
|
43
|
+
return { level: 'archkit', reason: `Technical blocker detected ("${kw}"). Opening ArchKit investigation.` };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Default: code bug → SpecKit
|
|
47
|
+
return { level: 'speckit', reason: 'No specific escalation trigger found. Treating as code bug (SpecKit fix).' };
|
|
48
|
+
}
|
|
49
|
+
export function createEscalation(cwd, description, forceLevel) {
|
|
50
|
+
const devkitDir = join(cwd, '.devkit');
|
|
51
|
+
const escalationsDir = join(devkitDir, 'qa', 'escalations');
|
|
52
|
+
if (!existsSync(devkitDir)) {
|
|
53
|
+
return {
|
|
54
|
+
created: false, id: '', path: '', level: 'speckit', reason: '',
|
|
55
|
+
error: '.devkit/ not found. Run "devkit init" first.',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
mkdirSync(escalationsDir, { recursive: true });
|
|
59
|
+
// Detect level
|
|
60
|
+
const { level, reason } = forceLevel
|
|
61
|
+
? { level: forceLevel, reason: `Manually escalated to ${forceLevel}.` }
|
|
62
|
+
: detectEscalationLevel(cwd, description);
|
|
63
|
+
// Generate ID
|
|
64
|
+
const existingFiles = existsSync(escalationsDir) ? readdirSync(escalationsDir).filter(f => f.startsWith('ESC-')) : [];
|
|
65
|
+
const nextNum = existingFiles.length + 1;
|
|
66
|
+
const id = `ESC-${nextNum.toString().padStart(3, '0')}`;
|
|
67
|
+
const filename = `${id}.md`;
|
|
68
|
+
const filePath = join(escalationsDir, filename);
|
|
69
|
+
const today = new Date().toISOString().split('T')[0];
|
|
70
|
+
const lines = [];
|
|
71
|
+
lines.push(`# ${id}: ${description}`);
|
|
72
|
+
lines.push('');
|
|
73
|
+
lines.push(`DATE: ${today}`);
|
|
74
|
+
lines.push('STATUS: open');
|
|
75
|
+
lines.push(`TRIGGERED_BY: ${description}`);
|
|
76
|
+
lines.push(`ESCALATED_TO: ${level}`);
|
|
77
|
+
lines.push(`REASON: ${reason}`);
|
|
78
|
+
lines.push('');
|
|
79
|
+
lines.push('## Analysis');
|
|
80
|
+
lines.push('');
|
|
81
|
+
switch (level) {
|
|
82
|
+
case 'speckit':
|
|
83
|
+
lines.push('**Type**: Code bug (code ≠ spec)');
|
|
84
|
+
lines.push('**Action**: Fix in SpecKit, no escalation needed.');
|
|
85
|
+
lines.push('');
|
|
86
|
+
lines.push('### What went wrong');
|
|
87
|
+
lines.push('');
|
|
88
|
+
lines.push('### Fix');
|
|
89
|
+
lines.push('');
|
|
90
|
+
break;
|
|
91
|
+
case 'archkit':
|
|
92
|
+
lines.push('**Type**: Invariant violation or technical blocker');
|
|
93
|
+
lines.push('**Action**: Open Investigation in ArchKit (`devkit investigate "..."`');
|
|
94
|
+
lines.push('');
|
|
95
|
+
lines.push('### Which invariant/assumption is broken');
|
|
96
|
+
lines.push('');
|
|
97
|
+
lines.push('### Proposed investigation');
|
|
98
|
+
lines.push('');
|
|
99
|
+
break;
|
|
100
|
+
case 'productkit':
|
|
101
|
+
lines.push('**Type**: UX invariant violation');
|
|
102
|
+
lines.push('**Action**: ProductKit investigation — review ux_invariants.md');
|
|
103
|
+
lines.push('');
|
|
104
|
+
lines.push('### Which UX invariant is violated');
|
|
105
|
+
lines.push('');
|
|
106
|
+
lines.push('### User impact');
|
|
107
|
+
lines.push('');
|
|
108
|
+
break;
|
|
109
|
+
case 'researchkit':
|
|
110
|
+
lines.push('**Type**: Research assumption rejected');
|
|
111
|
+
lines.push('**Action**: ResearchKit revision — update assumptions.md');
|
|
112
|
+
lines.push('');
|
|
113
|
+
lines.push('### Which assumption proved false');
|
|
114
|
+
lines.push('');
|
|
115
|
+
lines.push('### What we now know');
|
|
116
|
+
lines.push('');
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
lines.push('## Resolution');
|
|
120
|
+
lines.push('RESOLVED_BY: ');
|
|
121
|
+
lines.push('DATE_RESOLVED: ');
|
|
122
|
+
lines.push('DECISION_CREATED: ');
|
|
123
|
+
lines.push('');
|
|
124
|
+
writeFileSync(filePath, lines.join('\n'), 'utf-8');
|
|
125
|
+
return {
|
|
126
|
+
created: true,
|
|
127
|
+
id,
|
|
128
|
+
path: `qa/escalations/${filename}`,
|
|
129
|
+
level,
|
|
130
|
+
reason,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=escalate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escalate.js","sourceRoot":"","sources":["../src/escalate.ts"],"names":[],"mappings":"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"}
|
package/dist/gate.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Phase } from './status.js';
|
|
2
|
+
export interface GateCondition {
|
|
3
|
+
description: string;
|
|
4
|
+
satisfied: boolean;
|
|
5
|
+
detail?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface GateResult {
|
|
8
|
+
allowed: boolean;
|
|
9
|
+
currentPhase: Phase;
|
|
10
|
+
nextPhase: Phase | 'production';
|
|
11
|
+
conditions: GateCondition[];
|
|
12
|
+
}
|
|
13
|
+
export declare function checkGate(cwd: string, currentPhase: Phase): GateResult;
|
|
14
|
+
export declare function formatGate(result: GateResult): string;
|
|
15
|
+
//# sourceMappingURL=gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,KAAK,CAAC;IACpB,SAAS,EAAE,KAAK,GAAG,YAAY,CAAC;IAChC,UAAU,EAAE,aAAa,EAAE,CAAC;CAC/B;AAsND,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,GAAG,UAAU,CAqBtE;AAWD,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAyBrD"}
|