Main now takes release notes as one fragment per pull request (#787). The browser asks Google through /api/google/geocode, so the no-geocoder-request check now watches that route.
Windows runs npm.cmd through a shell, and passing an argument array with `shell: true` is deprecated in Node 24 (DEP0190). Every `npm run doctor` and every Pinokio install on Windows printed the warning. npmProcessSpec now takes the npm arguments and, on Windows, joins them into the command string; the arguments are fixed subcommands (`--version`, `ci`). Unix behavior is unchanged.
The flights records and the mesh-floor sampler kept identical copies of the equirectangular distance; both now import src/data/approxDistance.js. The changelog entry moves to changelog.d (#787), and CURRENT-STATE notes the antimeridian behaviour.
- i18n scanner: lastError sink, no false sinks on defaults and ternaries
- shared src/i18n/marker.js for modules that only mark strings
- wind field messages move to wind/fields.js; CITY_POIS imports from cityPois.js
- drop review IDs, change history and stale references from comments and docs
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Status pieces translate in one place (src/ui/statusText.js): a Local
ADS-B error with a single piece now translates, and the analyst card
splits empty-layer notes into pieces (Transit, Local ADS-B).
- Translate the ALPR retry chip text, the ECCC error on the Air quality
card, "Upstream response too large" and the "entry {n}" feed label.
- The unmarked-text check also sees error/loadingLabel/statusMessage/
status assignments, `status:` properties and showToast?.( /
this._showToast( calls; the scene import preview marks its pack
statuses, data and model-facing text carry i18n-ignore with a reason.
- Tests check the real code: the HUD locality formatter moves to
src/hudLocalityFormat.js, the unsaved-keys test pins the teardown.
- One copy each: city names come from src/cityPois.js, the GNSS HTTP
template and wind "field unavailable" texts; dead fallbacks removed.
- Leftovers of the reverted vessel-label change and the reformatting of
detectionHost.test.mjs / keySetup.test.mjs are back to main.
Catalogs: es/ru 2617 messages each, complete.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Fixes the P1 and the confirmed P2 findings of the final review of the
i18n branch.
- CI: the air-quality model no longer imports i18n (portable module),
so check:boundaries passes again.
- Air quality layer: named in the layer panel, HUD and voice; its
Weather card, bands and errors translate. A test keeps the layer-name
table in step with the layer registry.
- Layer statuses that still reached ru/es in English: GNSS, CelesTrak,
Transit loading and feed errors, launches, perimeters, ALPR, ECCC,
wind "field unavailable", Local ADS-B streaming lines.
- Voice and HUD: preset ids show city names ("Fly to San Francisco"),
the HUD city translates, cockpit refusals cover frame, aircraft and
satellite; empty Transit notes translate on the analyst card.
- tn() keeps a caller's formatted count ("12,345 map objects").
- Cyber HUD: the language button no longer covers the bottom-right
card or the cockpit position readout.
- CCTV buttons wrap only in non-English locales; English layout matches
main again.
- Switching language asks first when Provider Settings holds unsaved
keys.
Catalogs: es/ru 2611 messages each, complete.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
`--write` wrote CHANGELOG.md and then removed fragments one by one, so a
failure after the write left surviving fragments that a rerun spliced in
a second time.
The write is now staged. The assembled file goes into
changelog.d/.assembling/, the fragments are renamed in beside it, and
renaming the assembled file over CHANGELOG.md is the single commit
point. A run that fails rolls itself back when it can; otherwise the next
`npm run changelog` reads the staging directory and either restores the
fragments (assembled file still staged) or deletes the leftovers (batch
landed). `--check` reports a staged batch instead of reporting past it.
A failure-injection test makes every filesystem call in a `--write` fail
in turn, both as a one-off error and as a crash with no in-process
rollback. It asserts the retry produces exactly the uninterrupted
CHANGELOG.md, with each entry once and an empty directory. The test
fails against the previous write-then-delete and against delete-first.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Conflicts:
- CCTV HUD: main's datasheet FOV, capability range and spec summary,
with their labels translated; specFovCapabilityToken takes a format
so the HUD can pass a translated one. Datasheet resolution labels are
camera data (i18n-ignore).
- Transit: main's route labels and operator mode words, with the
generic words still translated; an operator's own word stays a name.
Catalogs: es/ru 2566 messages each, complete.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Number() reads null, blank strings and booleans as 0 (or 1), and
/api/cctv/sources sends an unknown number as JSON null. A source-pack
camera that left out its pose therefore reached the browser as zeros
clamped to each field's floor (north, pitch -2, FOV 20, range 120 m,
mount 6 m, ground 0 m) instead of taking the defaults, and a null or
blank position put the camera at 0,0.
toFiniteNumber (server) and safeNumber (browser) now return the fallback
for absent, blank and boolean values, as validateBox already does for
Recent Imagery. The same conversion fixes the per-pack paths: a Tallinn
row with a null heading no longer reads as a high-confidence north-facing
camera, a Caltrans camera with a blank elevation keeps its 150 m ground
prior, and TfL or Catalonia cameras with a null or blank coordinate are
dropped instead of kept at 0,0 or on the zero meridian.
Merges cleanly; weatherPanel.test.mjs arrived unformatted and is run
through prettier so format:check passes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Replaces the EN/ES/RU buttons in the Visual Presets dock with a picker
that scales to many languages: a globe button with the current code
next to the POWER UP chip, opening a list of languages named in their
own language with their codes, the current one first and checked. A
search field appears past 8 languages. Keyboard: arrows, Home/End,
Enter/Space, Esc, type-ahead; keys stay in the list while it is open.
Choosing a language still asks before dropping unsaved work, then
reloads. Phones get the globe alone and a full-width sheet; the layout
uses logical properties for right-to-left languages.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Upstream's #568 adds the Air quality layer to the Weather group (ECCC
AQHI, Canada only) with a band legend, worst-first list and voice
support.
- package-boundaries: both sides' entries unioned.
- layerPanel/weatherPanel tests: both sides' new tests kept; the
weatherPanel fixture follows upstream (legendCategorical: true, the
'list' block id) while our localized-history (K-6) test stays.
- air-quality strings marked: band labels and the provider label as
msg() data, the readings-list aria-label through t(); es/ru entries
added (+6 keys each).
- The synthetic air-quality allocation-benchmark titles follow the
file's own convention (// i18n-ignore) like TRK/VESSEL/CAMERA.
Also verified the auto-merged weatherPanel.js against upstream: ORDER
gains 'air-quality', OBSERVED stays slice(2, 5), and the data-driven
legendCategorical path is upstream's.
npm run i18n: complete (2559), no unmarked strings. npm test: only the
pre-existing environmental OPENAI_API_KEY leak fails. Build passes.
Upstream's #641 (bikeshare Toronto, city failures scoped to range with
partial outages read DEGRADED/STALE) replaced the layer-level GBFS
error strings this branch had msg()-marked, in the two paths that
conflicted.
- ingestion.js/viewport.js taken as upstream's per-city
_failedCityIds tracking; the layer-level error assignments are gone.
- 'GBFS fetch error' still reaches the panel via stats.error from
controls.js, so its mark moved there (translateFeedError keeps
translating it).
- 'GBFS status update failed' no longer exists anywhere: pruned from
es/ru and from the layerStatusText SITES table, which now pins the
controls.js site instead of the removed ones.
Also brings #581 (upstream-read caps, OpenSky 429 cooldown) - no i18n
surface.
npm run i18n: complete (2553), no unmarked strings. npm test: only the
pre-existing environmental OPENAI_API_KEY leak in devFreshDotenv fails.
Build passes.
The card never appeared: the Weather panel only passed five fixed ids and only
rendered lists and categorical legends for cyclones. Air quality now reaches
the panel, the legend style comes from the layer's descriptor, and any layer
with list items gets its list. Adds the voice manifest entry main now requires,
reads ECCC through the shared capped JSON reader with a 15 s deadline and the
row limit enforced, reports stale when every reading was too old, adds source
tests, links the ECCC licence and moves the changelog entry into Unreleased.
The build context excluded only .env, so .env.local and the like or
pinokio/ENVIRONMENT would be baked into image layers; exclude every dotenv
file except .env.example, plus local state and QA output. Pin the base to
CI's Node 24.14.0 by digest, default to the image's node user, and correct
the HOST comment. Log the trusted peers as the operator's when set. README
notes that MCP and ChatGPT sign-in voice are unavailable under Docker, and
how to trust no gateway when widening the publish.
Conflicts:
- KartaView viewer moved into the shared photoViewer.js on main; its
labels now take the provider name ("{name} street-level photo") and
are translated there.
- Weather: main's cloud filter strength slider, with its labels in t().
- Street Level caption: translated creator line plus main's licence.
Panoramax status and error texts are marked like KartaView's, and
"Panoramax answered HTTP {status}" gets a template in the panel and the
layer row. Catalogs: es/ru 2553 messages each, complete.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Both sides had merged the same main features (cockpit emergencies, GNSS
integrity, geo file import) with their own i18n. Conflicts keep this
branch's reviewed version; the 7 catalog entries only the other side
used are pruned. Newer main commits come in unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>