Commit Graph
22 Commits
Author SHA1 Message Date
Martino FerrariandClaude Opus 4.6 c1029a25df fix(udpscope): make the time-order test actually exercise the swap, guard the font copy
The ramp data in EmitsPointsInTimeOrder never produced a bucket whose maximum
preceded its minimum, so an implementation ordering the emitted pair by value
instead of by time would have passed. Replaced with an explicit two-bucket case
whose second bucket reverses the order.

file(COPY) is a hard configure error on a missing source, so a checkout without
the sibling StreamHub resources failed to configure despite the ASCII-icon
fallback the block above had just selected.

Plan amended to match on both points.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-27 19:39:14 +02:00
Martino FerrariandClaude Sonnet 4.6 fba4360c80 feat(udpscope): build scaffold and min/max envelope decimation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-27 17:27:41 +02:00
Martino Ferrari e03c60db25 Implemented and fixed many issues 2026-08-21 23:24:48 +02:00
Martino FerrariandClaude Sonnet 4.6 1f8592f854 fix: address all 9 findings from final calibration code review
- calibration.js: fix baseSignalName('[0]') parity with Go/C++ (>= 0 not > 0)
- calibration.test.js: add assertions for '[0]' edge case in two existing tests
- app.js: remove stale typeof guard around refreshVScaleMenu (always defined)
- app.js: call refreshTrigThresholdField on trig-signal change (both assignment sites)
- index.html: drop maxlength='16' on unit input; normaliseCal is the sole enforcer
- configcheck/main.go: delete dead nextOneOf function (no callers)
- hub_calibration_test.go: delete orphaned waitBroadcast comment (function never existed)
- calibration.go: correct arrayIndexSuffix comment to document known Go/C++ difference
- Docs/StreamHub-API.md: add calibration entry count and unit byte limits to §5 table
- spec: fix configReloaded missing path field, '16 chars'→'16 UTF-8 bytes', StreamString→char[], chain scenario→configcheck program, four→five new frames

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 07:57:28 +02:00
Martino FerrariandClaude Sonnet 4.6 e37eec0276 webui: add the Sources & Config sidebar section
Renames the "Add Source" section to "Sources & Config" and replaces the
fire-and-forget "Save list" button with Save and Reload, plus a one-line
status area that renders the hub's configSaved/configReloaded ack.

onConfigAck replaces the no-op stub Task 7 left behind. It branches on the
frame type because configSaved carries a path and configReloaded does not,
and surfaces the hub's error text on failure rather than failing silently.
The status is kept outside the DOM because buildSidebar() recreates this
section on every sources broadcast.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 07:23:08 +02:00
Martino FerrariandClaude Sonnet 4.6 5917ab1bf2 Restore calibration parity: revert unit-stripping from normaliseCal, fix CSV quoting at export
Finding 1: revert the comma/quote strip added in 3cb998c from
normaliseCal() in calibration.js. The strip broke byte-identical parity
with Go CalConfig.Normalise and C++ StreamHub::SetCalibrationEntry, both
of which only trim whitespace and cap at 16 UTF-8 bytes. Delete the
companion test that asserted the now-removed behaviour (suite returns to
18 tests).

Finding 2: fix the actual CSV-safety problem at the point of use in
exportAllCSV() in app.js. Header cells (time column and signal columns)
are now RFC 4180-quoted: wrapped in double quotes with any embedded
double quote doubled. This safely handles units or signal names that
contain commas or quotes without touching normaliseCal.

Finding 3: update two stale comments in app.js that called the trigger
threshold or rawFromNorm result 'raw' — Task 9 moved trig.threshold into
calibrated units throughout, so the comments now say 'calibrated'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 01:15:13 +02:00
Martino FerrariandClaude Sonnet 4.6 3cb998c5da webui: calibrate CSV export, trigger threshold and unit display
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 00:55:07 +02:00
Martino FerrariandClaude Sonnet 4.6 4908c039a5 fix(webui): keep cal-invalid styling on focused field during hub broadcast
refreshVScaleMenu() was unconditionally removing the cal-invalid class
from all three calibration inputs, which silently cleared the red-border
error indicator on a field the user was editing whenever a hub
calibration broadcast arrived. Apply the same focused-element guard
already used for .value writes so a rejected value's error styling
persists until the user corrects it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 00:52:04 +02:00
Martino FerrariandClaude Sonnet 4.6 4e3a90b2c6 webui: add calibration editor to the V-Scale toolbar
Adds the Cal row (Scale / Offset / Unit / Reset) to #vscale-menu, its
CSS, and the refreshVScaleMenu() / commitCal() logic that wires it to
calTable and the hub via setCalibrationWS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 00:48:39 +02:00
Martino Ferrari 0e9ec61226 webui: apply per-signal calibration to the whole display path 2026-08-17 00:43:18 +02:00
Martino FerrariandClaude Opus 4.6 7312dd0ca0 docs(calibration.js): explain why one UTF-8 repair pass suffices in JS
TextEncoder always emits well-formed UTF-8, so truncation can strand at
most a lead byte plus three continuations — one repair pass covers it.
The C++ hub needs a loop because its input is raw bytes off the wire.
Also drops a dead variable from the byte-boundary test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-17 00:41:00 +02:00
Martino FerrariandClaude Opus 4.6 48d62c1f80 fix(calibration.js): cap unit at 16 UTF-8 bytes, matching both hubs
normaliseCal was using String.length/.slice() (UTF-16 code units), so
multi-byte characters like °, Ω, µ could slip through oversized. Now uses
TextEncoder to slice at 16 bytes, then repairs any incomplete trailing
UTF-8 sequence by walking back over continuation bytes to find the lead
byte and dropping the incomplete rune — exactly mirroring Go's
utf8.DecodeLastRuneInString loop and the C++ walk-back in
StreamHub::SetCalibrationEntry. Adds 4 new test cases covering the
non-ASCII/boundary scenarios, and corrects the canonical test command in
the task-6 report to 'cd Client/udpstreamer && node --test'.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-17 00:36:01 +02:00
Martino FerrariandClaude Sonnet 4.6 21d084d2ea webui: add pure calibration module with unit tests
Implements Calib JS module (calibration.js) with affine transform primitives,
CalTable, and normaliseCal matching Go CalConfig.Normalise semantics; 14 node
--test cases all pass. Loads before app.js in index.html.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-17 00:29:53 +02:00
Martino Ferrari ff5ad22447 included jitter correction on client 2026-08-13 10:28:43 +02:00
Martino Ferrari f0f83110a4 fix(debugger): extract MarteController into an importable controller package
Client/debugger was entirely package main, which Go forbids importing from
another module ("is a program, not an importable package") -- discovered
while wiring the new debugclient E2E tool against NewHeadlessMarteController.
Move martecontrol.go and its test into a new marte2debugger/controller
subpackage (package controller) and update Client/debugger/main.go to call
controller.NewMarteController/controller.DangerousCommandsEnabled. No
behavioral change to the browser-facing server.
2026-07-01 19:18:08 +02:00
Martino Ferrari 269b2c4d97 refactor(debugger): extract MarteController sink so it can run headless
Add a sink func(v any) field so MarteController's event stream can be
routed somewhere other than the browser WebSocket hub. NewMarteController
now sets sink to broadcast through the hub as before; a new
NewHeadlessMarteController(sink) constructor builds an instance with
hub == nil for the upcoming debugclient E2E tool. Direct m.hub.* calls
(SetSourceState/UpdateConfigForSource/PushDataForSource) are now guarded
with nil checks so a headless controller doesn't panic.
2026-07-01 19:12:41 +02:00
Martino Ferrari 0bea41f866 Implemented better testing and fixed skipepd frames 2026-07-01 16:39:34 +02:00
Martino Ferrari 4702d0a217 Implemented qt port + e2e 2026-06-26 09:11:10 +02:00
Martino Ferrari 0412c20edd Implemented client datasource 2026-06-25 00:45:45 +02:00
Martino Ferrari dd7dd22cb0 Implemented history writer 2026-06-14 14:09:51 +02:00
Martino Ferrari f25bd7f08e Implemented new C++ logic 2026-06-12 15:25:13 +02:00
Martino Ferrari 617b5bd712 Initial release 2026-05-29 13:29:59 +02:00