kryptheon 0.1.25 → 0.1.26
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/kryptheon-dashboard-page.js +5 -0
- package/kryptheon-dashboard.js +60 -2
- package/kryptheon-store.js +2 -0
- package/package.json +1 -1
|
@@ -459,6 +459,7 @@
|
|
|
459
459
|
meta.appendChild(sevTag(f.severity));
|
|
460
460
|
meta.appendChild(statusTag(f));
|
|
461
461
|
meta.appendChild(el('span', 'tag ' + (CHECK_TONE[f.check] || ''), CHECK_NAME[f.check] || f.check));
|
|
462
|
+
if (f.from === 'nightly' || f.from === 'both') meta.appendChild(el('span', 'tag', f.from === 'both' ? 'also nightly' : 'nightly'));
|
|
462
463
|
meta.appendChild(el('span', 'f-where', f.where));
|
|
463
464
|
left.appendChild(meta);
|
|
464
465
|
head.appendChild(left);
|
|
@@ -564,6 +565,9 @@
|
|
|
564
565
|
st.appendChild(el('span', 'tag ' + (STATE_TONE[c.state] || ''), c.state));
|
|
565
566
|
card.appendChild(st);
|
|
566
567
|
if (c.what) card.appendChild(el('div', 'c-what', c.what));
|
|
568
|
+
// What the nightly run inside the database last said - its own answer,
|
|
569
|
+
// not this terminal's, so it gets its own line.
|
|
570
|
+
if (c.nightly) card.appendChild(el('div', 'c-what', c.nightly));
|
|
567
571
|
if (c.runnable && c.enabled) {
|
|
568
572
|
var run = button('sm', 'play', 'Run now', function () { runChecks([c.id], run); });
|
|
569
573
|
run.setAttribute('data-action', 'run');
|
|
@@ -600,6 +604,7 @@
|
|
|
600
604
|
['test-results/', 'screenshots and traces from runs that broke'],
|
|
601
605
|
['code-findings.json', 'the last read of your frontend code'],
|
|
602
606
|
['night-last.json', 'the last database check'],
|
|
607
|
+
['night-nightly.json', 'what the nightly run inside your database last said'],
|
|
603
608
|
['snapshot.json', 'what your files looked like at the last look'],
|
|
604
609
|
['changes.jsonl', 'every look: what changed, what broke, what got fixed'],
|
|
605
610
|
['fixes.jsonl', 'every re-check and its verdict'],
|
package/kryptheon-dashboard.js
CHANGED
|
@@ -251,6 +251,28 @@ function nextAction(findings, steps) {
|
|
|
251
251
|
return { kind: 'quiet', title: 'Nothing open' };
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
/**
|
|
255
|
+
* One sentence about the nightly run inside the database, or null when
|
|
256
|
+
* kryptheon-night has never been asked. Its four states are four different
|
|
257
|
+
* answers, and none of the other three may read as "nothing found": not set
|
|
258
|
+
* up, set up and never run, set up with nothing scheduled, and stopped.
|
|
259
|
+
*/
|
|
260
|
+
function nightlyLine(nightly) {
|
|
261
|
+
if (!nightly) return null;
|
|
262
|
+
const day = (iso) => String(iso || '').slice(0, 16).replace('T', ' ');
|
|
263
|
+
const read = ' (as of ' + day(nightly.readAt) + ')';
|
|
264
|
+
if (!nightly.installed) return 'Nightly run in your database: not set up. npx kryptheon-night install sets it up.' + read;
|
|
265
|
+
const idle = nightly.active ? '' : ' Nothing is scheduled, so it is not running - npx kryptheon-night install sets it up again.';
|
|
266
|
+
if (!nightly.ranAt) return 'Nightly run in your database: set up, and it has not run yet.' + idle + read;
|
|
267
|
+
const when = 'Nightly run in your database, ' + day(nightly.ranAt) + ': ';
|
|
268
|
+
if (nightly.stopped) return when + 'it could not check - ' + nightly.stopped + idle + read;
|
|
269
|
+
const n = (nightly.findings || []).length;
|
|
270
|
+
const skipped = (nightly.notChecked || []).length;
|
|
271
|
+
return when + (n ? n + (n === 1 ? ' problem found.' : ' problems found.')
|
|
272
|
+
: 'nothing got through ' + (nightly.attacksRun || 0) + ' attacks.') +
|
|
273
|
+
(skipped ? ' ' + skipped + ' ' + (skipped === 1 ? 'part was' : 'parts were') + ' not tested.' : '') + idle + read;
|
|
274
|
+
}
|
|
275
|
+
|
|
254
276
|
/**
|
|
255
277
|
* Everything the page shows, from the store alone. Findings from every check
|
|
256
278
|
* are put into one list, each carrying the same fields - severity, status,
|
|
@@ -264,6 +286,10 @@ function buildState(root, env) {
|
|
|
264
286
|
const baselines = readJson(paths.baselines) || {};
|
|
265
287
|
const code = readJson(paths.codeFindings);
|
|
266
288
|
const night = readJson(paths.nightLast);
|
|
289
|
+
// What the nightly run inside the database last said, kept by
|
|
290
|
+
// kryptheon-night whenever it connects. Not the same answer as night:
|
|
291
|
+
// that one is the scan last run from this terminal.
|
|
292
|
+
const nightly = readJson(paths.nightNightly);
|
|
267
293
|
|
|
268
294
|
const findings = [];
|
|
269
295
|
|
|
@@ -331,6 +357,33 @@ function buildState(root, env) {
|
|
|
331
357
|
}
|
|
332
358
|
}
|
|
333
359
|
|
|
360
|
+
// The nightly run's findings, said as coming from it. One both answers
|
|
361
|
+
// share is shown once, with the newer date - the same problem found twice
|
|
362
|
+
// is still one problem to fix.
|
|
363
|
+
if (nightly && nightly.ranAt && config.enabled.data) {
|
|
364
|
+
for (const f of nightly.findings || []) {
|
|
365
|
+
const item = {
|
|
366
|
+
check: 'data',
|
|
367
|
+
from: 'nightly',
|
|
368
|
+
severity: f.severity,
|
|
369
|
+
status: f.status || 'confirmed',
|
|
370
|
+
evidence: (f.status || 'confirmed') === 'confirmed' ? 'runtime confirmed' : 'code analysis',
|
|
371
|
+
confidence: (f.status || 'confirmed') === 'confirmed' ? 'high' : 'medium',
|
|
372
|
+
where: f.table + (f.column ? '.' + f.column : ''),
|
|
373
|
+
headline: f.headline,
|
|
374
|
+
detail: f.body || '',
|
|
375
|
+
fixPrompt: f.fixPrompt || '',
|
|
376
|
+
when: nightly.ranAt,
|
|
377
|
+
};
|
|
378
|
+
const same = findings.find((o) => o.check === 'data' && changes.findingKey(o) === changes.findingKey(item));
|
|
379
|
+
if (!same) findings.push(item);
|
|
380
|
+
else {
|
|
381
|
+
same.from = 'both';
|
|
382
|
+
if (!same.when || item.when > same.when) same.when = item.when;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
334
387
|
const rank = { 'HIGH CRITICAL': 0, CRITICAL: 0, HIGH: 1, MEDIUM: 2, LOW: 3 };
|
|
335
388
|
findings.sort((a, b) => (rank[a.severity] ?? 9) - (rank[b.severity] ?? 9) ||
|
|
336
389
|
(a.status === 'confirmed' ? 0 : 1) - (b.status === 'confirmed' ? 0 : 1));
|
|
@@ -359,9 +412,14 @@ function buildState(root, env) {
|
|
|
359
412
|
else if (!config.enabled[c.id]) state = 'switched off';
|
|
360
413
|
else if (c.id === 'regression') state = !recordings ? 'no recordings yet' : !lastRun ? 'never run' : lastRun.failed ? 'problems found' : 'last run held';
|
|
361
414
|
else if (c.id === 'frontend') state = !code ? 'never run' : (code.findings || []).length ? 'things to check' : 'nothing found';
|
|
362
|
-
else if (c.id === 'data')
|
|
415
|
+
else if (c.id === 'data') {
|
|
416
|
+
const ranNightly = nightly && nightly.ranAt && !nightly.stopped;
|
|
417
|
+
state = !night && !ranNightly ? 'never run here'
|
|
418
|
+
: findings.some((f) => f.check === 'data') ? 'problems found' : 'last run held';
|
|
419
|
+
}
|
|
363
420
|
return {
|
|
364
421
|
id: c.id, label: c.label, available: c.available, enabled: config.enabled[c.id], state: state, what: c.what || '',
|
|
422
|
+
nightly: c.id === 'data' ? nightlyLine(nightly) : null,
|
|
365
423
|
// Runnable from the page: what needs nothing the page cannot supply. The
|
|
366
424
|
// database check needs a connection string, which stays in the terminal.
|
|
367
425
|
runnable: c.available && (c.id === 'frontend' || (c.id === 'regression' && recordings > 0)),
|
|
@@ -372,7 +430,7 @@ function buildState(root, env) {
|
|
|
372
430
|
codeAt: code ? code.checkedAt : null,
|
|
373
431
|
recordings: recordings,
|
|
374
432
|
lastRunAt: lastRun ? lastRun.runAt : null,
|
|
375
|
-
nightAt: night ? nightWhen : null,
|
|
433
|
+
nightAt: [night ? nightWhen : null, nightly && nightly.ranAt].filter(Boolean).sort().pop() || null,
|
|
376
434
|
});
|
|
377
435
|
|
|
378
436
|
// Every look Kryptheon took - by `verify`, or by the dashboard's own watch -
|
package/kryptheon-store.js
CHANGED
|
@@ -45,6 +45,7 @@ const FILES = {
|
|
|
45
45
|
history: 'history.jsonl',
|
|
46
46
|
testResults: 'test-results',
|
|
47
47
|
nightLast: 'night-last.json',
|
|
48
|
+
nightNightly: 'night-nightly.json',
|
|
48
49
|
codeFindings: 'code-findings.json',
|
|
49
50
|
config: 'config.json',
|
|
50
51
|
snapshot: 'snapshot.json',
|
|
@@ -132,6 +133,7 @@ function pathsIn(dir) {
|
|
|
132
133
|
history: path.join(dir, FILES.history),
|
|
133
134
|
testResults: path.join(dir, FILES.testResults),
|
|
134
135
|
nightLast: path.join(dir, FILES.nightLast),
|
|
136
|
+
nightNightly: path.join(dir, FILES.nightNightly),
|
|
135
137
|
codeFindings: path.join(dir, FILES.codeFindings),
|
|
136
138
|
config: path.join(dir, FILES.config),
|
|
137
139
|
snapshot: path.join(dir, FILES.snapshot),
|