@codyswann/lisa 2.233.1 → 2.235.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/cli/doctor.d.ts +9 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +3 -1
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/ui-ci-quality-jobs-compute.d.ts +46 -0
- package/dist/cli/ui-ci-quality-jobs-compute.d.ts.map +1 -0
- package/dist/cli/ui-ci-quality-jobs-compute.js +178 -0
- package/dist/cli/ui-ci-quality-jobs-compute.js.map +1 -0
- package/dist/cli/ui-ci-quality-jobs-parse.d.ts +15 -0
- package/dist/cli/ui-ci-quality-jobs-parse.d.ts.map +1 -0
- package/dist/cli/ui-ci-quality-jobs-parse.js +109 -0
- package/dist/cli/ui-ci-quality-jobs-parse.js.map +1 -0
- package/dist/cli/ui-ci-quality-jobs.d.ts +22 -0
- package/dist/cli/ui-ci-quality-jobs.d.ts.map +1 -0
- package/dist/cli/ui-ci-quality-jobs.js +160 -0
- package/dist/cli/ui-ci-quality-jobs.js.map +1 -0
- package/dist/cli/ui-cmd.d.ts +2 -0
- package/dist/cli/ui-cmd.d.ts.map +1 -1
- package/dist/cli/ui-cmd.js +9 -1
- package/dist/cli/ui-cmd.js.map +1 -1
- package/dist/cli/ui-lisa-version.d.ts +36 -0
- package/dist/cli/ui-lisa-version.d.ts.map +1 -0
- package/dist/cli/ui-lisa-version.js +86 -0
- package/dist/cli/ui-lisa-version.js.map +1 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/ui/index.html +274 -40
package/ui/index.html
CHANGED
|
@@ -260,6 +260,7 @@
|
|
|
260
260
|
height: 8px;
|
|
261
261
|
border-radius: 50%;
|
|
262
262
|
flex: none;
|
|
263
|
+
background: var(--muted);
|
|
263
264
|
}
|
|
264
265
|
.dot.ok {
|
|
265
266
|
background: var(--good);
|
|
@@ -270,6 +271,9 @@
|
|
|
270
271
|
.dot.fail {
|
|
271
272
|
background: var(--crit);
|
|
272
273
|
}
|
|
274
|
+
.dot.unknown {
|
|
275
|
+
background: var(--muted);
|
|
276
|
+
}
|
|
273
277
|
.badge.pass {
|
|
274
278
|
background: var(--good-soft);
|
|
275
279
|
color: var(--good);
|
|
@@ -1252,8 +1256,7 @@
|
|
|
1252
1256
|
type="button"
|
|
1253
1257
|
title="Lisa health — click for details"
|
|
1254
1258
|
>
|
|
1255
|
-
<span class="dot
|
|
1256
|
-
· up to date
|
|
1259
|
+
<span class="dot" aria-hidden="true"></span> @codyswann/lisa · checking…
|
|
1257
1260
|
</button>
|
|
1258
1261
|
<button
|
|
1259
1262
|
class="icon-btn"
|
|
@@ -4451,7 +4454,12 @@
|
|
|
4451
4454
|
t: "text",
|
|
4452
4455
|
v: "oxlint then ESLint over the whole repo — the fast rule set",
|
|
4453
4456
|
},
|
|
4454
|
-
{
|
|
4457
|
+
{
|
|
4458
|
+
t: "status",
|
|
4459
|
+
jobId: "lint",
|
|
4460
|
+
v: null,
|
|
4461
|
+
reason: "checking…",
|
|
4462
|
+
},
|
|
4455
4463
|
],
|
|
4456
4464
|
[
|
|
4457
4465
|
{ t: "mono", v: "🐢 Slow Lint Rules" },
|
|
@@ -4459,22 +4467,42 @@
|
|
|
4459
4467
|
t: "text",
|
|
4460
4468
|
v: "The expensive rules deferred from local lint (import cycles, namespace checks)",
|
|
4461
4469
|
},
|
|
4462
|
-
{
|
|
4470
|
+
{
|
|
4471
|
+
t: "status",
|
|
4472
|
+
jobId: "lint_slow",
|
|
4473
|
+
v: null,
|
|
4474
|
+
reason: "checking…",
|
|
4475
|
+
},
|
|
4463
4476
|
],
|
|
4464
4477
|
[
|
|
4465
4478
|
{ t: "mono", v: "🔍 Type Check" },
|
|
4466
4479
|
{ t: "text", v: "tsc --noEmit across the project" },
|
|
4467
|
-
{
|
|
4480
|
+
{
|
|
4481
|
+
t: "status",
|
|
4482
|
+
jobId: "typecheck",
|
|
4483
|
+
v: null,
|
|
4484
|
+
reason: "checking…",
|
|
4485
|
+
},
|
|
4468
4486
|
],
|
|
4469
4487
|
[
|
|
4470
4488
|
{ t: "mono", v: "📐 Check Formatting" },
|
|
4471
4489
|
{ t: "text", v: "Prettier in check mode — no writes" },
|
|
4472
|
-
{
|
|
4490
|
+
{
|
|
4491
|
+
t: "status",
|
|
4492
|
+
jobId: "format",
|
|
4493
|
+
v: null,
|
|
4494
|
+
reason: "checking…",
|
|
4495
|
+
},
|
|
4473
4496
|
],
|
|
4474
4497
|
[
|
|
4475
4498
|
{ t: "mono", v: "🏗️ Build" },
|
|
4476
4499
|
{ t: "text", v: "Compiles the project to catch build breaks" },
|
|
4477
|
-
{
|
|
4500
|
+
{
|
|
4501
|
+
t: "status",
|
|
4502
|
+
jobId: "build",
|
|
4503
|
+
v: null,
|
|
4504
|
+
reason: "checking…",
|
|
4505
|
+
},
|
|
4478
4506
|
],
|
|
4479
4507
|
[
|
|
4480
4508
|
{ t: "mono", v: "🧪 Run Unit Tests" },
|
|
@@ -4482,12 +4510,22 @@
|
|
|
4482
4510
|
t: "text",
|
|
4483
4511
|
v: "Unit suite with the coverage floors from Testing & coverage enforced",
|
|
4484
4512
|
},
|
|
4485
|
-
{
|
|
4513
|
+
{
|
|
4514
|
+
t: "status",
|
|
4515
|
+
jobId: "test:unit",
|
|
4516
|
+
v: null,
|
|
4517
|
+
reason: "checking…",
|
|
4518
|
+
},
|
|
4486
4519
|
],
|
|
4487
4520
|
[
|
|
4488
4521
|
{ t: "mono", v: "🧪 Run Integration Tests" },
|
|
4489
4522
|
{ t: "text", v: "Integration suite (30-minute timeout)" },
|
|
4490
|
-
{
|
|
4523
|
+
{
|
|
4524
|
+
t: "status",
|
|
4525
|
+
jobId: "test:integration",
|
|
4526
|
+
v: null,
|
|
4527
|
+
reason: "checking…",
|
|
4528
|
+
},
|
|
4491
4529
|
],
|
|
4492
4530
|
[
|
|
4493
4531
|
{ t: "mono", v: "🧪 Run E2E Tests" },
|
|
@@ -4495,7 +4533,12 @@
|
|
|
4495
4533
|
t: "text",
|
|
4496
4534
|
v: "Playwright end-to-end tests, auto-detected from playwright.config + a test:e2e script",
|
|
4497
4535
|
},
|
|
4498
|
-
{
|
|
4536
|
+
{
|
|
4537
|
+
t: "status",
|
|
4538
|
+
jobId: "test:e2e",
|
|
4539
|
+
v: null,
|
|
4540
|
+
reason: "checking…",
|
|
4541
|
+
},
|
|
4499
4542
|
],
|
|
4500
4543
|
[
|
|
4501
4544
|
{ t: "mono", v: "🎭 Playwright E2E Tests" },
|
|
@@ -4503,7 +4546,12 @@
|
|
|
4503
4546
|
t: "text",
|
|
4504
4547
|
v: "Web-export e2e run — a required check on staging via ruleset",
|
|
4505
4548
|
},
|
|
4506
|
-
{
|
|
4549
|
+
{
|
|
4550
|
+
t: "status",
|
|
4551
|
+
jobId: "playwright_e2e",
|
|
4552
|
+
v: null,
|
|
4553
|
+
reason: "checking…",
|
|
4554
|
+
},
|
|
4507
4555
|
],
|
|
4508
4556
|
[
|
|
4509
4557
|
{ t: "mono", v: "📱 Maestro Cloud E2E" },
|
|
@@ -4511,7 +4559,12 @@
|
|
|
4511
4559
|
t: "text",
|
|
4512
4560
|
v: "Mobile end-to-end flows on Maestro Cloud",
|
|
4513
4561
|
},
|
|
4514
|
-
{
|
|
4562
|
+
{
|
|
4563
|
+
t: "status",
|
|
4564
|
+
jobId: "maestro_e2e",
|
|
4565
|
+
v: null,
|
|
4566
|
+
reason: "checking…",
|
|
4567
|
+
},
|
|
4515
4568
|
],
|
|
4516
4569
|
[
|
|
4517
4570
|
{ t: "mono", v: "🧭 E2E Route Coverage" },
|
|
@@ -4519,7 +4572,12 @@
|
|
|
4519
4572
|
t: "text",
|
|
4520
4573
|
v: "Static gate: % of expo-router routes reached by Playwright specs and Maestro flows, against the floors in e2e.thresholds.json — auto-enabled on Expo projects, a no-op elsewhere",
|
|
4521
4574
|
},
|
|
4522
|
-
{
|
|
4575
|
+
{
|
|
4576
|
+
t: "status",
|
|
4577
|
+
jobId: "e2e_coverage",
|
|
4578
|
+
v: null,
|
|
4579
|
+
reason: "checking…",
|
|
4580
|
+
},
|
|
4523
4581
|
],
|
|
4524
4582
|
[
|
|
4525
4583
|
{ t: "mono", v: "🧬 Mutation Testing Gate" },
|
|
@@ -4529,9 +4587,9 @@
|
|
|
4529
4587
|
},
|
|
4530
4588
|
{
|
|
4531
4589
|
t: "status",
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4590
|
+
jobId: "test:mutation",
|
|
4591
|
+
v: null,
|
|
4592
|
+
reason: "checking…",
|
|
4535
4593
|
},
|
|
4536
4594
|
],
|
|
4537
4595
|
[
|
|
@@ -4540,7 +4598,12 @@
|
|
|
4540
4598
|
t: "text",
|
|
4541
4599
|
v: "Requires feat/fix PRs to add or extend an e2e verification spec",
|
|
4542
4600
|
},
|
|
4543
|
-
{
|
|
4601
|
+
{
|
|
4602
|
+
t: "status",
|
|
4603
|
+
jobId: "verification_coverage",
|
|
4604
|
+
v: null,
|
|
4605
|
+
reason: "checking…",
|
|
4606
|
+
},
|
|
4544
4607
|
],
|
|
4545
4608
|
[
|
|
4546
4609
|
{ t: "mono", v: "🗑️ Dead Code Detection" },
|
|
@@ -4548,7 +4611,12 @@
|
|
|
4548
4611
|
t: "text",
|
|
4549
4612
|
v: "knip — unused files, exports, and dependencies",
|
|
4550
4613
|
},
|
|
4551
|
-
{
|
|
4614
|
+
{
|
|
4615
|
+
t: "status",
|
|
4616
|
+
jobId: "dead_code",
|
|
4617
|
+
v: null,
|
|
4618
|
+
reason: "checking…",
|
|
4619
|
+
},
|
|
4552
4620
|
],
|
|
4553
4621
|
[
|
|
4554
4622
|
{ t: "mono", v: "🔎 AST Grep Scan" },
|
|
@@ -4556,7 +4624,12 @@
|
|
|
4556
4624
|
t: "text",
|
|
4557
4625
|
v: "Structural code rules from sgconfig.yml",
|
|
4558
4626
|
},
|
|
4559
|
-
{
|
|
4627
|
+
{
|
|
4628
|
+
t: "status",
|
|
4629
|
+
jobId: "sg_scan",
|
|
4630
|
+
v: null,
|
|
4631
|
+
reason: "checking…",
|
|
4632
|
+
},
|
|
4560
4633
|
],
|
|
4561
4634
|
[
|
|
4562
4635
|
{ t: "mono", v: "🔒 Security Scan" },
|
|
@@ -4564,20 +4637,31 @@
|
|
|
4564
4637
|
t: "text",
|
|
4565
4638
|
v: "Dependency audit — high and critical advisories in production dependencies",
|
|
4566
4639
|
},
|
|
4567
|
-
{
|
|
4640
|
+
{
|
|
4641
|
+
t: "status",
|
|
4642
|
+
jobId: "npm_security_scan",
|
|
4643
|
+
v: null,
|
|
4644
|
+
reason: "checking…",
|
|
4645
|
+
},
|
|
4568
4646
|
],
|
|
4569
4647
|
[
|
|
4570
4648
|
{ t: "mono", v: "🔍 SonarCloud SAST" },
|
|
4571
4649
|
{ t: "text", v: "Static analysis via SonarCloud" },
|
|
4572
|
-
{
|
|
4650
|
+
{
|
|
4651
|
+
t: "status",
|
|
4652
|
+
jobId: "sonarcloud",
|
|
4653
|
+
v: null,
|
|
4654
|
+
reason: "checking…",
|
|
4655
|
+
},
|
|
4573
4656
|
],
|
|
4574
4657
|
[
|
|
4575
4658
|
{ t: "mono", v: "🛡️ Snyk" },
|
|
4576
4659
|
{ t: "text", v: "Snyk dependency vulnerability scan" },
|
|
4577
4660
|
{
|
|
4578
4661
|
t: "status",
|
|
4579
|
-
|
|
4580
|
-
|
|
4662
|
+
jobId: "snyk",
|
|
4663
|
+
v: null,
|
|
4664
|
+
reason: "checking…",
|
|
4581
4665
|
},
|
|
4582
4666
|
],
|
|
4583
4667
|
[
|
|
@@ -4586,15 +4670,21 @@
|
|
|
4586
4670
|
t: "text",
|
|
4587
4671
|
v: "Secret scanning — also a required check via the base ruleset",
|
|
4588
4672
|
},
|
|
4589
|
-
{
|
|
4673
|
+
{
|
|
4674
|
+
t: "status",
|
|
4675
|
+
jobId: "secret_scanning",
|
|
4676
|
+
v: null,
|
|
4677
|
+
reason: "checking…",
|
|
4678
|
+
},
|
|
4590
4679
|
],
|
|
4591
4680
|
[
|
|
4592
4681
|
{ t: "mono", v: "📜 FOSSA" },
|
|
4593
4682
|
{ t: "text", v: "License compliance check" },
|
|
4594
4683
|
{
|
|
4595
4684
|
t: "status",
|
|
4596
|
-
|
|
4597
|
-
|
|
4685
|
+
jobId: "license_compliance",
|
|
4686
|
+
v: null,
|
|
4687
|
+
reason: "checking…",
|
|
4598
4688
|
},
|
|
4599
4689
|
],
|
|
4600
4690
|
[
|
|
@@ -4603,7 +4693,12 @@
|
|
|
4603
4693
|
t: "text",
|
|
4604
4694
|
v: "DAST baseline scan against zap_target_url with per-rule IGNORE/WARN/FAIL decisions",
|
|
4605
4695
|
},
|
|
4606
|
-
{
|
|
4696
|
+
{
|
|
4697
|
+
t: "status",
|
|
4698
|
+
jobId: "zap_baseline",
|
|
4699
|
+
v: null,
|
|
4700
|
+
reason: "checking…",
|
|
4701
|
+
},
|
|
4607
4702
|
],
|
|
4608
4703
|
[
|
|
4609
4704
|
{ t: "mono", v: "🧾 Compliance Validation" },
|
|
@@ -4613,8 +4708,9 @@
|
|
|
4613
4708
|
},
|
|
4614
4709
|
{
|
|
4615
4710
|
t: "status",
|
|
4616
|
-
|
|
4617
|
-
|
|
4711
|
+
jobId: "compliance_validation",
|
|
4712
|
+
v: null,
|
|
4713
|
+
reason: "checking…",
|
|
4618
4714
|
},
|
|
4619
4715
|
],
|
|
4620
4716
|
[
|
|
@@ -4623,7 +4719,12 @@
|
|
|
4623
4719
|
t: "text",
|
|
4624
4720
|
v: "Pauses the run until the target GitHub environment’s reviewers approve",
|
|
4625
4721
|
},
|
|
4626
|
-
{
|
|
4722
|
+
{
|
|
4723
|
+
t: "status",
|
|
4724
|
+
jobId: "approval_gate",
|
|
4725
|
+
v: null,
|
|
4726
|
+
reason: "checking…",
|
|
4727
|
+
},
|
|
4627
4728
|
],
|
|
4628
4729
|
],
|
|
4629
4730
|
},
|
|
@@ -5543,13 +5644,20 @@
|
|
|
5543
5644
|
chip.appendChild(el("span", "", esc(cell.v)));
|
|
5544
5645
|
td.appendChild(chip);
|
|
5545
5646
|
} else if (cell.t === "status") {
|
|
5546
|
-
if (cell.
|
|
5647
|
+
if (cell.jobId) td.dataset.jobId = cell.jobId;
|
|
5648
|
+
if (cell.v === true) {
|
|
5547
5649
|
td.appendChild(el("span", "badge pass", "✓ active"));
|
|
5548
|
-
} else {
|
|
5650
|
+
} else if (cell.v === false) {
|
|
5549
5651
|
td.appendChild(el("span", "badge fail", "✗ off"));
|
|
5550
5652
|
if (cell.reason) {
|
|
5551
5653
|
td.appendChild(el("span", "status-why", esc(cell.reason)));
|
|
5552
5654
|
}
|
|
5655
|
+
} else {
|
|
5656
|
+
// null/undefined = unknown — never fabricate "off" or "active"
|
|
5657
|
+
td.appendChild(el("span", "badge warn", "unknown"));
|
|
5658
|
+
if (cell.reason) {
|
|
5659
|
+
td.appendChild(el("span", "status-why", esc(cell.reason)));
|
|
5660
|
+
}
|
|
5553
5661
|
}
|
|
5554
5662
|
} else if (cell.t === "run") {
|
|
5555
5663
|
const cls =
|
|
@@ -6082,6 +6190,125 @@
|
|
|
6082
6190
|
list.appendChild(item);
|
|
6083
6191
|
});
|
|
6084
6192
|
}
|
|
6193
|
+
/**
|
|
6194
|
+
* Paint `#healthChip` from the lisa-version probe.
|
|
6195
|
+
* green=ok (up to date), amber=warn (behind), unknown≠ok.
|
|
6196
|
+
* READ-ONLY — never offers an upgrade action.
|
|
6197
|
+
* @param probes - Live-status probe map from /api/status
|
|
6198
|
+
*/
|
|
6199
|
+
function applyLisaVersion(probes) {
|
|
6200
|
+
const chip = document.getElementById("healthChip");
|
|
6201
|
+
if (!chip) return;
|
|
6202
|
+
const raw =
|
|
6203
|
+
probes && Object.hasOwn(probes, "lisa-version")
|
|
6204
|
+
? probes["lisa-version"]
|
|
6205
|
+
: undefined;
|
|
6206
|
+
const result =
|
|
6207
|
+
raw === undefined
|
|
6208
|
+
? {
|
|
6209
|
+
state: "unknown",
|
|
6210
|
+
reason: "missing-probe",
|
|
6211
|
+
message: "The lisa-version probe was not reported",
|
|
6212
|
+
}
|
|
6213
|
+
: normalizeLiveStatusResult(raw);
|
|
6214
|
+
const setChip = (dotClass, label) => {
|
|
6215
|
+
chip.innerHTML = "";
|
|
6216
|
+
const dot = el("span", "dot" + (dotClass ? " " + dotClass : ""));
|
|
6217
|
+
dot.setAttribute("aria-hidden", "true");
|
|
6218
|
+
chip.appendChild(dot);
|
|
6219
|
+
chip.appendChild(document.createTextNode(" " + label));
|
|
6220
|
+
};
|
|
6221
|
+
if (
|
|
6222
|
+
result.state === "value" &&
|
|
6223
|
+
result.value &&
|
|
6224
|
+
typeof result.value === "object"
|
|
6225
|
+
) {
|
|
6226
|
+
const current = result.value.current;
|
|
6227
|
+
const latest = result.value.latest;
|
|
6228
|
+
const outdated = result.value.outdated === true;
|
|
6229
|
+
if (
|
|
6230
|
+
typeof current === "string" &&
|
|
6231
|
+
typeof latest === "string" &&
|
|
6232
|
+
current.length > 0 &&
|
|
6233
|
+
latest.length > 0
|
|
6234
|
+
) {
|
|
6235
|
+
if (outdated) {
|
|
6236
|
+
setChip(
|
|
6237
|
+
"warn",
|
|
6238
|
+
"@codyswann/lisa " + current + " · latest " + latest
|
|
6239
|
+
);
|
|
6240
|
+
return;
|
|
6241
|
+
}
|
|
6242
|
+
setChip("ok", "@codyswann/lisa " + current + " · up to date");
|
|
6243
|
+
return;
|
|
6244
|
+
}
|
|
6245
|
+
}
|
|
6246
|
+
if (result.state === "unknown") {
|
|
6247
|
+
const reason = result.reason || "unknown";
|
|
6248
|
+
const message = result.message || "Version status unavailable";
|
|
6249
|
+
setChip(
|
|
6250
|
+
"unknown",
|
|
6251
|
+
"@codyswann/lisa · unknown (" + reason + ": " + message + ")"
|
|
6252
|
+
);
|
|
6253
|
+
return;
|
|
6254
|
+
}
|
|
6255
|
+
setChip(
|
|
6256
|
+
"unknown",
|
|
6257
|
+
"@codyswann/lisa · unknown (invalid-value: lisa-version probe returned an unusable value)"
|
|
6258
|
+
);
|
|
6259
|
+
}
|
|
6260
|
+
/**
|
|
6261
|
+
* Paint the CI Quality jobs Active column from the ci-quality-jobs probe.
|
|
6262
|
+
* Never leaves a fabricated active/off value when the probe is unknown.
|
|
6263
|
+
* @param probes - Live-status probe map from /api/status
|
|
6264
|
+
*/
|
|
6265
|
+
function applyCiQualityJobs(probes) {
|
|
6266
|
+
const table = (DATA.sections.ci.blocks || []).find(
|
|
6267
|
+
block => block.type === "table" && block.card === "Quality jobs"
|
|
6268
|
+
);
|
|
6269
|
+
if (!table) return;
|
|
6270
|
+
const result = normalizeLiveStatusResult(
|
|
6271
|
+
probes && Object.hasOwn(probes, "ci-quality-jobs")
|
|
6272
|
+
? probes["ci-quality-jobs"]
|
|
6273
|
+
: {
|
|
6274
|
+
state: "unknown",
|
|
6275
|
+
reason: "missing-probe",
|
|
6276
|
+
message: "The ci-quality-jobs probe was not reported",
|
|
6277
|
+
}
|
|
6278
|
+
);
|
|
6279
|
+
const byId = new Map();
|
|
6280
|
+
if (
|
|
6281
|
+
result.state === "value" &&
|
|
6282
|
+
result.value &&
|
|
6283
|
+
typeof result.value === "object" &&
|
|
6284
|
+
Array.isArray(result.value.jobs)
|
|
6285
|
+
) {
|
|
6286
|
+
result.value.jobs.forEach(job => {
|
|
6287
|
+
if (job && typeof job.id === "string") byId.set(job.id, job);
|
|
6288
|
+
});
|
|
6289
|
+
}
|
|
6290
|
+
table.rows.forEach(cells => {
|
|
6291
|
+
const status = cells.find(cell => cell.t === "status" && cell.jobId);
|
|
6292
|
+
if (!status) return;
|
|
6293
|
+
if (result.state !== "value") {
|
|
6294
|
+
status.v = null;
|
|
6295
|
+
status.reason =
|
|
6296
|
+
result.reason + (result.message ? ": " + result.message : "");
|
|
6297
|
+
return;
|
|
6298
|
+
}
|
|
6299
|
+
const job = byId.get(status.jobId);
|
|
6300
|
+
if (!job) {
|
|
6301
|
+
status.v = null;
|
|
6302
|
+
status.reason = "missing-job: probe omitted " + status.jobId;
|
|
6303
|
+
return;
|
|
6304
|
+
}
|
|
6305
|
+
status.v = job.active;
|
|
6306
|
+
status.reason = typeof job.reason === "string" ? job.reason : "";
|
|
6307
|
+
});
|
|
6308
|
+
const current = activeSection;
|
|
6309
|
+
renderAll();
|
|
6310
|
+
showSection(current);
|
|
6311
|
+
}
|
|
6085
6312
|
async function hydrateLiveStatuses() {
|
|
6086
6313
|
try {
|
|
6087
6314
|
const response = await fetch("/api/status", {
|
|
@@ -6089,15 +6316,22 @@
|
|
|
6089
6316
|
});
|
|
6090
6317
|
if (!response.ok) throw new Error("HTTP " + response.status);
|
|
6091
6318
|
const snapshot = await response.json();
|
|
6092
|
-
|
|
6319
|
+
const probes = liveStatusProbeMap(snapshot);
|
|
6320
|
+
renderLiveStatuses(probes);
|
|
6321
|
+
// Quality jobs re-renders the page; paint the version chip after.
|
|
6322
|
+
applyCiQualityJobs(probes);
|
|
6323
|
+
applyLisaVersion(probes);
|
|
6093
6324
|
} catch (error) {
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
}
|
|
6325
|
+
const message =
|
|
6326
|
+
error instanceof Error ? error.message : String(error);
|
|
6327
|
+
const unavailable = {
|
|
6328
|
+
state: "unknown",
|
|
6329
|
+
reason: "status-unavailable",
|
|
6330
|
+
message,
|
|
6331
|
+
};
|
|
6332
|
+
renderLiveStatuses({ transport: unavailable });
|
|
6333
|
+
applyCiQualityJobs({ "ci-quality-jobs": unavailable });
|
|
6334
|
+
applyLisaVersion({ "lisa-version": unavailable });
|
|
6101
6335
|
}
|
|
6102
6336
|
}
|
|
6103
6337
|
|