Skip to content

Add Scenarios 9-24#200

Merged
thkruz merged 15 commits into
mainfrom
dev
Jun 16, 2026
Merged

Add Scenarios 9-24#200
thkruz merged 15 commits into
mainfrom
dev

Conversation

@thkruz

@thkruz thkruz commented Jun 16, 2026

Copy link
Copy Markdown
Owner

This pull request adds comprehensive end-to-end Playwright test suites for two new simulation scenarios ("Customer Pass" and "Thermal Anomaly") and improves the robustness of navigation tests by making URL matching host-agnostic. The new scenario test files automate realistic operator workflows, validating all objectives and mission completion for each scenario.

New scenario test automation:

  • Added scenario10-full-completion.spec.ts, a full test suite for Scenario 10 ("Customer Pass"), automating all mission objectives including antenna tracking mode changes and HPA backoff adjustments. This includes helper functions for scenario-specific actions and checks for mission completion.
  • Added scenario13-full-completion.spec.ts, a full test suite for Scenario 13 ("Thermal Anomaly"), automating objectives such as BUC gain adjustment and trend analysis, with helper functions for BUC gain configuration and scenario workflow.

Navigation test robustness:

  • Updated URL matching in navigation.spec.ts to accept both localhost and 127.0.0.1 as valid hosts, making navigation tests less brittle and more environment-agnostic.## Description

Testing

  • Unit tests pass (npm test)
  • E2E tests pass locally (npm run test:e2e)

thkruz added 10 commits June 11, 2026 05:50
Use 127.0.0.1 for the Playwright baseURL/webServer so a foreign dev server
bound to ::1:3000 cannot shadow the webpack server, allow 127.0.0.1 in the
Supabase approved-domain check (app hard-crashed to a blank page on
non-approved hosts), and make the navigation spec's URL assertion
host-agnostic.
Qualified-operations arc: morning rounds, customer pass, planned-maintenance
handover cycle, thermal trend judgment, rain-fade hold, frequency
coordination, and the cascade-failure capstone. Adds TIDEMARK-3 to the
satellite roster, registers all eight scenarios in both registries, and
validates each with a Playwright full-completion spec.

Key corrections made during validation: handovers stage the receiving
station cold (the transfer swaps RF authority - dual illumination otherwise),
HPA-before-BUC safety sequencing in S16, traffic-owner condition params,
receiver IF tuning for ME-02, and S13 thermal/gain math consistent with the
BUC model.
… Document engine support

Crisis-operations opener: Solar Event (new 'sun-transit' weather type drives
an RX-only sky-noise rise/peak/fall on the antenna - demod loss and
self-recovery are real), Satellite Anomaly (scenario-local drifting TM-2
variant, step-track contingency), Train the New Hire (new Working Document
panel accumulates the quick-reference card from documentLine quiz params),
and Dual Outage (multi-site triage with an adversarial rule-out beat).

All four validated with full-completion Playwright specs (88 tests);
targeted 1-16 regression (S3/S9/S14) green after the engine extensions.
Crisis-operations conclusion: Hostile RF (new InterferenceManager injects a
duty-cycled uplink jammer relayed through the transponder; jamming-vs-
interference discrimination and the denial-vs-intrusion data-layer check),
End-of-Life Planning (Working Document produces a board-level sunset report),
Emergency Bypass (new ACU automation-fault flag forces verified manual ops),
and the Constellation Crisis capstone (five concurrent tracks under single-
operator incident command, Working Document as the incident log).

Engine additions are additive and regression-clean (1-16 + S17-20 green):
InterferenceManager, antenna isAcuAutomationFaulted gating, and the
documentLine/workingDocument plumbing. All four validated with full-completion
specs (batch-2 gate 77/77). Campaign plan marked fully Built.
SimulationManager's constructor started the game loop synchronously, which
emits Events.UPDATE before getInstance() has assigned the singleton instance_.
ObjectivesManager.evaluateCondition_ calls SimulationManager.getInstance() for
every condition, so any objective evaluated during that first synchronous tick
re-entered the constructor and recursed until 'Maximum call stack size
exceeded'. Defer the first tick to requestAnimationFrame so the constructor
returns and instance_ is assigned before any UPDATE fires.
The pre-game 'already complete?' check awaits a remote GET that retries failed
fetches with exponential backoff (~7s total). Because it is awaited before the
mission-control screen transitions, an unreachable or slow backend (offline, or
a CORS-blocked dev origin) stalled the Start button for 5-8 seconds. Cap the
check at 1.5s via Promise.race and proceed into the scenario on timeout - the
worst case is replaying an already-complete scenario. The losing request is
caught so it cannot surface as an unhandled rejection.
Passive verification conditions (beacon present, receiver locked, HPA enabled,
GPSDO locked, etc.) were satisfied from ambient simulation state, so their
checklist rows showed pre-ticked before the operator ever opened the relevant
screen - teaching the wrong habit. Add an opt-in observation latch:

- Condition param requiresObservation + observationTab: the condition does not
  count from ambient state alone; it latches satisfied only once the value is
  true WHILE the operator is viewing the observation tab, then stays checked.
- Condition.hidden: a condition still enforced for completion but not rendered
  as a checklist row - used to require the correct tab on qualified-operator
  scenarios without spelling out which tab.

Applied to Scenario 9 as the reference: every tab-active row hidden (9+ players
are expected to know where to look) and each ambient value-condition gated on
observation. The objective still completes the instant the operator opens the
right tab. observed latches through checkpoint save/restore and resets when an
objective is replayed.
Hide every tab-active checklist row on the qualified-operator scenarios (10-24)
so the player is not handed which tab to open, and require observation
(requiresObservation + observationTab) on the ambient value-conditions in the
verify/check/baseline objectives - beacon present, receiver lock, C/N margin,
HPA enabled, antenna lock, etc. These rows no longer pre-tick from scenario
state; they latch only once the operator views the relevant screen.

Gated: S10-S18 verify objectives (the rounds/baseline/anomaly checks where the
values are true at activation). Action objectives (power-up, repoint, mode
changes, backoff sets) are left alone - those values result from the operator's
own action in the same step.
Apply requiresObservation to the ambient value-conditions in the Phase 1
verify/health-check objectives (GPSDO lock, LNB powered/stable/ref-locked,
beacon present, receiver lock + C/N) so those rows no longer pre-tick from
scenario state. Phase 1 keeps its tab-active rows VISIBLE - Charlie still walks
new trainees to each tab - so only the value rows are gated, matched to the
tab where each is actually observed (gps-timing / rx-analysis / dashboard).
Power-up, acquire, and configure action objectives are left untouched.
@thkruz thkruz self-assigned this Jun 16, 2026
@thkruz thkruz added type: feature New functionality type: enhancement Improvement to existing feature type: docs Documentation only priority: high Must fix before launch labels Jun 16, 2026
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

Dependency Review

The following issues were found:

  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ✅ 0 package(s) with unknown licenses.
  • ⚠️ 3 packages with OpenSSF Scorecard issues.

View full job summary

thkruz added 3 commits June 15, 2026 22:33
The sun-transit feature added WeatherManager.updateSunTransit_, which calls
antenna.updateSkyNoiseDegradation(). The mock antenna lacked that method and the
skyNoiseDegradation_dB state field, so 13 tests failed with TypeError. Add both
to createMockAntenna so the mock matches the real Antenna interface.
The game loop moved from App into SimulationManager, which defers its first tick
to requestAnimationFrame and is torn down by the router when it navigates to the
campaign-selection page during init (Router.showPage -> SimulationManager.destroy).
App.create() therefore no longer emits UPDATE/DRAW. Replace the stale assertion
with a create() contract test (instantiation + window.signalRange + ROUTE_CHANGED)
and a dedicated game-loop test that drives one tick on a live SimulationManager.
Use the @app/ alias for any import that reaches outside its own directory and
keep ./ for same-directory siblings. Consolidate @engine/ usage outside the
engine subtree into @app/engine/ so @app is the single internal alias.

This removes the alias-vs-relative duplication footgun where the same module
could be referenced two ways (e.g. ./events/event-bus vs @app/events/event-bus),
which previously let App and SimulationManager disagree on the same import.

351 imports across 110 files; src/engine/ excluded.
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 80.31% 12776 / 15908
🔵 Statements 79.18% 13292 / 16787
🔵 Functions 78.17% 2360 / 3019
🔵 Branches 64.37% 5624 / 8736
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
package.json 100% 100% 100% 100%
src/app.ts 88.57% 100% 75% 91.17% 36, 58, 63, 95
src/router.ts 92.22% 77.14% 81.81% 94.31% 50, 54-58
src/scenario-manager.ts 100% 100% 100% 100%
src/campaigns/nats/campaign-data.ts 100% 100% 100% 100%
src/campaigns/nats/satellites.ts 100% 100% 100% 100%
src/campaigns/nats/scenario1.ts 100% 100% 100% 100%
src/campaigns/nats/scenario10.ts 100% 100% 100% 100%
src/campaigns/nats/scenario11.ts 100% 100% 100% 100%
src/campaigns/nats/scenario12.ts 100% 100% 100% 100%
src/campaigns/nats/scenario13.ts 100% 100% 100% 100%
src/campaigns/nats/scenario14.ts 100% 100% 100% 100%
src/campaigns/nats/scenario15.ts 100% 100% 100% 100%
src/campaigns/nats/scenario16.ts 100% 100% 100% 100%
src/campaigns/nats/scenario17.ts 22.22% 0% 0% 25% 53-64, 399-518
src/campaigns/nats/scenario18.ts 100% 100% 100% 100%
src/campaigns/nats/scenario19.ts 100% 100% 100% 100%
src/campaigns/nats/scenario2.ts 100% 100% 100% 100%
src/campaigns/nats/scenario20.ts 28.57% 0% 0% 33.33% 58-69, 629
src/campaigns/nats/scenario21.ts 100% 100% 100% 100%
src/campaigns/nats/scenario22.ts 100% 100% 100% 100%
src/campaigns/nats/scenario23.ts 100% 100% 100% 100%
src/campaigns/nats/scenario24.ts 100% 100% 100% 100%
src/campaigns/nats/scenario3.ts 100% 100% 100% 100%
src/campaigns/nats/scenario4.ts 100% 100% 100% 100%
src/campaigns/nats/scenario6.ts 100% 100% 100% 100%
src/campaigns/nats/scenario7.ts 100% 100% 100% 100%
src/campaigns/nats/scenario8.ts 100% 100% 100% 100%
src/campaigns/nats/scenario9.ts 100% 100% 100% 100%
src/dev-menu/dev-menu-box.ts 0.77% 0% 7.69% 0.78% 30-345
src/equipment/base-equipment.ts 83.05% 81.48% 100% 81.48% 52, 60-72
src/equipment/antenna/antenna-core.ts 72.31% 66.89% 75.86% 72.6% 278, 346, 362, 426-480, 555-556, 563-564, 570-583, 600-601, 649-650, 722, 739-764, 804-821, 827-830, 847-881, 924-925, 953, 1009, 1066-1076, 1131-1133, 1270-1292, 1302-1308, 1312-1315, 1361, 1366-1372, 1406-1407, 1445, 1450-1493, 1504-1514, 1602-1609, 1628-1630, 1663-1671, 1877-1921
src/equipment/antenna/antenna-ui-basic.ts 94.11% 87.5% 81.81% 94.11% 71, 79
src/equipment/antenna/antenna-ui-modern.ts 98.46% 81.25% 91.66% 100% 160
src/equipment/antenna/antenna-ui-standard.ts 95.58% 88.46% 70% 95.58% 82, 90, 98
src/equipment/antenna/step-track-controller.ts 96% 80.76% 100% 96% 170, 179, 184
src/equipment/real-time-spectrum-analyzer/analyzer-control-box.ts 100% 100% 100% 100%
src/equipment/real-time-spectrum-analyzer/analyzer-control.ts 93.45% 76.92% 83.33% 94.28% 118-122, 335, 379, 406-409
src/equipment/real-time-spectrum-analyzer/real-time-spectrum-analyzer.ts 74.17% 49.15% 76.66% 75.23% 188, 209-222, 226, 227, 228, 310-322, 337-359, 401-404, 422-432, 439-454, 502-503, 568-569, 573-574
src/equipment/real-time-spectrum-analyzer/spectrum-data-processor.ts 96.26% 88.88% 100% 97% 109, 114, 221, 248
src/equipment/real-time-spectrum-analyzer/analyzer-control/base-control-button.ts 78.57% 100% 70% 78.57% 65-73
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-ampt-btn/ac-ampt-btn.ts 83.16% 57.14% 82.35% 83.16% 40-41, 44-45, 48-49, 133-147, 157
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-bw-btn/ac-bw-btn.ts 81.17% 64% 100% 81.17% 78, 91-93, 97-99, 114, 127-128, 133-134, 138, 149-151
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-freq-btn/ac-freq-btn.ts 57.69% 37.03% 60% 57.69% 39, 42, 45, 62-88, 98-103, 142-144, 169-205
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-ghz-btn/ac-ghz-btn.ts 100% 90% 100% 100%
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-hz-btn/ac-hz-btn.ts 94.11% 70% 100% 94.11% 26
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-khz-btn/ac-khz-btn.ts 94.44% 70% 100% 94.44% 27
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-mhz-btn/ac-mhz-btn.ts 94.11% 70% 100% 94.11% 27
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-mkr-btn/ac-mkr-btn.ts 92.3% 62.5% 80% 92.3% 37
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-mkr2-btn/ac-mkr2-btn.ts 100% 50% 100% 100%
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-mode-btn/ac-mode-btn.ts 100% 100% 100% 100%
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-save-btn/ac-save-btn.ts 96.96% 66.66% 100% 96.96% 30
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-span-btn/ac-span-btn.ts 63.38% 22.22% 54.54% 63.38% 64-66, 82-106, 119-120, 125-130, 142-147
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-sweep-btn/ac-sweep-btn.ts 100% 100% 100% 100%
src/equipment/real-time-spectrum-analyzer/analyzer-control/ac-trace-btn/ac-trace-btn.ts 93.38% 71.87% 95% 93.38% 178-183, 208, 217-219
src/equipment/real-time-spectrum-analyzer/rtsa-screen/rtsa-screen.ts 92.1% 91.66% 100% 92.1% 87-89
src/equipment/real-time-spectrum-analyzer/rtsa-screen/spectral-density-plot.ts 88.56% 66.66% 90% 88.5% 186, 290-291, 309, 334-338, 345, 403-410, 412-418, 420-426, 460-470, 565, 644-660, 665, 678
src/equipment/real-time-spectrum-analyzer/rtsa-screen/waterfall-display.ts 84.24% 67.92% 78.57% 85.92% 146-149, 153, 261-291
src/equipment/receiver/receiver.ts 93.99% 82.08% 93.05% 95.07% 387, 391, 395, 679, 695, 723, 761, 768, 778, 782, 791, 795, 798, 899-900, 905-906, 931, 933, 935, 942, 945, 1076-1077, 1101
src/equipment/rf-front-end/rf-front-end-core.ts 66.19% 77.92% 66.66% 67.14% 164, 172-190, 216-217, 220-221, 232-233, 236-237, 248, 264, 361, 406-493
src/equipment/rf-front-end/rf-front-end-ui-standard.ts 65% 85.71% 52.63% 65.38% 171-173, 177-179, 183-185, 189-191, 195-197, 201-203, 207-209, 213-215, 219-221, 259
src/equipment/rf-front-end/agc-module/agc-module-core.ts 100% 100% 100% 100%
src/equipment/rf-front-end/agc-module/agc-module-factory.ts 100% 100% 100% 100%
src/equipment/rf-front-end/agc-module/agc-module-ui-headless.ts 50% 100% 75% 50% 25
src/equipment/rf-front-end/buc-module/buc-module-core.ts 98.11% 97.93% 100% 98.05% 219, 384-385
src/equipment/rf-front-end/buc-module/buc-module-factory.ts 40% 57.14% 100% 40% 22-26
src/equipment/rf-front-end/buc-module/buc-module-ui-standard.ts 62.79% 47.61% 23.8% 65.06% 40, 71, 151-163, 172, 177-179, 187-189, 207-250, 259, 263
src/equipment/rf-front-end/coupler-module/coupler-module-factory.ts 100% 100% 100% 100%
src/equipment/rf-front-end/coupler-module/coupler-module.ts 89.58% 63.93% 96.66% 92.22% 152, 161-162, 275, 286, 294-295, 320, 324
src/equipment/rf-front-end/filter-module/filter-module-core.ts 89.65% 33.33% 76.92% 89.65% 111-116
src/equipment/rf-front-end/filter-module/filter-module-factory.ts 40% 57.14% 100% 40% 22-26
src/equipment/rf-front-end/filter-module/filter-module-ui-standard.ts 55.17% 45.83% 38.46% 58.18% 33-36, 53, 108-120, 129-130, 152-178, 187, 191, 212, 218-219
src/equipment/rf-front-end/gpsdo-module/gpsdo-module-core.ts 99.48% 96.82% 91.17% 100% 265
src/equipment/rf-front-end/gpsdo-module/gpsdo-module-factory.ts 100% 100% 100% 100%
src/equipment/rf-front-end/gpsdo-module/gpsdo-module-ui-standard.ts 87.96% 87.5% 89.28% 87.85% 168-169, 174-176, 181-186, 195, 215, 241
src/equipment/rf-front-end/hpa-module/hpa-module-core.ts 97.43% 92.85% 100% 97.34% 171, 188, 193
src/equipment/rf-front-end/hpa-module/hpa-module-factory.ts 100% 100% 100% 100%
src/equipment/rf-front-end/hpa-module/hpa-module-ui-standard.ts 53.12% 42.1% 27.77% 54.83% 33, 68, 128-140, 148-149, 154-216, 240, 244
src/equipment/rf-front-end/lnb-module/lnb-module-core.ts 93.27% 88.88% 100% 93.27% 115-117, 214-215, 293-294, 397
src/equipment/rf-front-end/lnb-module/lnb-module-factory.ts 40% 57.14% 100% 40% 22-26
src/equipment/rf-front-end/lnb-module/lnb-module-ui-standard.ts 60.25% 50% 35% 62.66% 34, 51, 141-153, 161-162, 167, 194-225, 234, 238, 269-273
src/equipment/rf-front-end/notch-filter-module/notch-filter-module-core.ts 100% 100% 100% 100%
src/equipment/rf-front-end/notch-filter-module/notch-filter-module-factory.ts 100% 100% 100% 100%
src/equipment/rf-front-end/notch-filter-module/notch-filter-module-ui-headless.ts 50% 100% 75% 50% 25
src/equipment/rf-front-end/omt-module/omt-module-factory.ts 100% 100% 100% 100%
src/equipment/rf-front-end/omt-module/omt-module.ts 63.63% 39.53% 86.36% 65.62% 77, 141, 163-166, 169-173, 186-201, 218-237, 251
src/equipment/transmitter/transmitter.ts 83.82% 73.65% 87.71% 84.26% 186-235, 423, 474-477, 506-519, 561, 592-615, 644-651
src/events/event-bus.ts 100% 100% 100% 100%
src/events/events.ts 100% 100% 100% 100%
src/interference/interference-manager.ts 5.55% 7.14% 37.5% 6.25% 48-63, 68-119
src/modal/hint-modal.ts 3.17% 0% 11.11% 3.77% 34-200
src/modal/objective-failed-modal.ts 60% 33.33% 58.33% 62.5% 33, 50-65, 79, 89, 90-112, 128, 143-146
src/modal/quiz-modal.ts 90.68% 69.64% 89.65% 94.68% 71, 112-113, 135, 142, 151, 217, 260, 282, 320, 362, 369-372, 401, 450-452
src/objectives/objective-types.ts 0% 0% 0% 0%
src/objectives/objectives-manager.ts 69.81% 64.38% 84.47% 74.5% 143, 152, 308-443, 450, 463, 499, 518, 556, 583, 614-615, 630, 717, 728, 803, 823, 828-833, 918, 931, 949, 987, 1029-1053, 1081-1086, 1136, 1143, 1156-1157, 1163-1164, 1179, 1182-1187, 1200-1204, 1215, 1222, 1237, 1242, 1343-1360, 1376, 1389, 1464, 1476-1481, 1488-1489, 1505, 1514, 1540, 1550, 1560, 1570, 1579, 1586, 1596, 1614, 1624, 1634, 1660, 1668, 1672, 1677, 1683, 1692, 1702, 1710, 1738, 1744, 1765-1772, 1785, 1805, 1834, 1846, 1854, 1860, 1870, 1876, 1886, 1891, 1898, 1903, 1910, 1916, 1924, 1930, 1937, 1943, 1950, 1955, 1961, 1967-1968, 1986-2049, 2056, 2066, 2075, 2082-2085, 2095-2096, 2126-2311
src/pages/base-page.ts 89.89% 78.57% 82.35% 91.48% 105, 110, 191-196, 216-218, 265, 280, 281
src/pages/campaign-selection.ts 86.9% 82% 77.27% 91.02% 44, 49, 67, 71-72, 77-80, 99, 247, 262, 269
src/pages/sandbox-page.ts 95.45% 80% 100% 95.45% 116, 144, 159
src/pages/scenario-selection.ts 91.13% 85.07% 77.14% 93.42% 83, 88, 129, 143, 153, 172, 378-387, 394, 400, 406, 434, 479, 491
src/pages/layout/body/body.ts 100% 100% 100% 100%
src/pages/layout/footer/footer.ts 100% 83.33% 100% 100%
src/pages/layout/header/header.ts 89.09% 67.74% 79.31% 89.9% 160-161, 173, 183, 199, 227, 233, 267, 291-292, 304, 331
src/pages/mission-control/asset-tree-sidebar.ts 76.24% 51.42% 86.04% 77.58% 193, 197, 201, 233-238, 247, 250, 253-295, 324-334, 338
src/pages/mission-control/mission-control-page.ts 73.95% 57.14% 66.66% 74.19% 175-176, 203-246, 253-255
src/pages/mission-control/tabbed-canvas.ts 81.77% 59.3% 97.14% 81.72% 59, 111, 118-120, 142-143, 210-212, 332-338, 347-349, 373-379, 388-390, 412-418, 427-429, 451-457, 466-468, 490-496, 505-507
src/pages/mission-control/tabs/acu-control-tab.ts 94.58% 69.87% 86.66% 96.08% 499, 513, 547, 551, 555, 563, 597, 634, 671, 681, 700, 707, 923, 964-965, 984-989, 1008
src/pages/mission-control/tabs/dashboard-tab.ts 88.8% 58.04% 86.04% 89.32% 407-419, 524, 526, 586-587, 589-590, 592-593, 604-606, 679-680, 682-683, 729, 732-735, 792-797, 804-809, 817-822, 835-838, 843
src/pages/mission-control/tabs/mission-overview-tab.ts 100% 72.22% 100% 100%
src/pages/mission-control/tabs/satellite-dashboard-tab.ts 98.54% 76% 100% 100% 219, 222
src/pages/sandbox/equipment.ts 79.2% 51.72% 82.35% 79.16% 91-97, 112-122, 126, 132-133, 177, 184, 190, 209
src/scenarios/sandbox.ts 100% 100% 100% 100%
src/scenarios/working-document-manager.ts 23.21% 6.66% 35.71% 27.08% 51-132, 137-138
src/simulation/simulation-manager.ts 80% 60% 46.15% 85.1% 48, 50, 75, 96-108
src/sync/storage.ts 83.33% 100% 83.33% 82.92% 23-24, 52-65
src/sync/sync-manager.ts 83.01% 60.29% 85.18% 83.01% 114, 142-143, 167, 178-184, 191-194, 201, 217, 222-223, 279-282, 291-296
src/weather/weather-manager.ts 95.06% 94.54% 100% 95% 127-129, 134
Generated in workflow #239 for commit 715b391 by the Vitest Coverage Report Action

@thkruz thkruz merged commit 7e13ba5 into main Jun 16, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: high Must fix before launch type: docs Documentation only type: enhancement Improvement to existing feature type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant