Commit graph

59 commits

Author SHA1 Message Date
a7b67ed106 docs(fusion): standalone track-fusion gating demonstration
Some checks failed
Holocron Frontend CI / lint-and-test (push) Has been cancelled
Self-contained page documenting where track fusion works and where the
prototype silently missed duplicates. Draggable contact pair over a
to-scale cell grid, live per-gate readout, and the coverage-by-latitude
comparison. Opens straight off disk, no build or server needed.
2026-08-04 19:25:49 -04:00
dd034d8315 chore(beads): sync issue exports 2026-08-04 18:41:22 -04:00
fd7c1672db feat(fusion): latitude-correct track fusion with deterministic clustering
Some checks failed
Holocron Frontend CI / lint-and-test (push) Has been cancelled
Rework the fuseTracks() prototype into a pure, tested module and wire it
into the asset pipeline so the Fused layer is populated correctly.

The prototype picked the right algorithm (uniform spatial grid) but the
search neighbourhood was a fixed 3x3 ring, which is narrower than the
2886 m distance gate at every European latitude because a degree of
longitude shrinks toward the pole. Measured, that lost 6% of true
duplicate pairs at 52N and 41% at 70N: the duplicates the feature exists
to remove stayed on the Contacts layer.

- TrackIndex derives the ring radius from the gate at the worst latitude
  it will scan, so coverage is guaranteed rather than assumed. Global,
  non-negative cell coordinates remove the hidden dependency on the
  Europe display clamp being applied first.
- Gates report each measurement, and an unmeasurable gate resolves by
  motionPolicy instead of passing on a NaN comparison. Default refuses to
  fuse: losing a real contact is worse than showing a duplicate.
- Clustering is union-find by minimum identifier, so the canonical track
  is a pure function of the report set and no longer flips with map
  iteration order.
- The index is reconciled from state at one point, making a stale cell
  entry structurally impossible rather than dependent on every retirement
  path remembering to clean up.
- Fusion runs outside the state updater, throttled to one pass per 150 ms
  instead of a full rescan per message, and returns the same map by
  identity when no verdict changed.

38 module tests plus 7 hook integration tests, including a sweep
asserting no duplicate is missed anywhere in the theatre.
2026-08-04 18:41:04 -04:00
f221231f5a chore(beads): sync interactions.jsonl export
Some checks failed
Holocron Frontend CI / lint-and-test (push) Has been cancelled
2026-08-04 17:59:51 -04:00
a2e4294307 fix(frontend): clear the remaining tsc --noEmit errors
tsc --noEmit reported 39 errors across 13 files; the build never caught them
because vite transpiles without type checking. Root causes rather than casts:

- userPreferencesStore: DEFAULT_PREFERENCES inferred each field from its own
  default, pinning minimapPosition to 'top-right' and theme to 'dark', so no
  setter could assign any other member of the union. Declared UserPreferences
  explicitly. This also fixes MiniMap's 'no overlap' comparison.
- ReportPanel: ReportData.assets was a structural clone of Asset with an index
  signature, which nothing could satisfy and the panel cast back to Asset
  anyway. It is Asset[] now, which unblocks App.tsx and the story.
- reporting: getAssetPosition also accepts raw payloads spelling the fields
  longitude/latitude, so position is typed as the union it actually holds.
- useDraggablePanel: style is Partial<DraggablePanelStyle>; the empty-until-
  dragged branch never satisfied Record<string, never>, and callers spreading
  it over their defaults tripped duplicate-property errors.
- types: declare AssetDescription.callsign, a field the MQTT bridge sends.
- messageTemplates: widen a possibly-undefined local, and use a ternary so the
  first operation is not typed 'false | Record'.
- stories: drop unused React imports.

tsc --noEmit is clean, eslint unchanged at 0 errors, 117 tests pass.
2026-08-04 17:59:41 -04:00
dd2863f1f4 fix(globe): use endPosition for report-shape mouse-move previews
Cesium's MOUSE_MOVE event carries startPosition/endPosition, not position. The
reporting-mode handler read movement.position and passed undefined to
camera.pickEllipsoid, which threw 'windowPosition is required.' on every mouse
move while drawing — so the live rubber-band preview for rectangle, circle and
hexagon never rendered. Shapes still completed because LEFT_CLICK does carry
position, which hid the breakage.

getClickLonLat now takes a Cartesian2 directly so each call site passes the
field its own event actually has. The drawing helpers become arrow consts:
hoisted function declarations do not inherit the non-null narrowing of the
viewer guard above them, which was 15 of the file's type errors.
2026-08-04 17:59:30 -04:00
ce1af083a2 fix(frontend): stop useWebSocket reconnecting after an intentional close
ws.close() left the socket's handlers attached, so its own onclose fired and
scheduled an exponential-backoff reconnect. Under StrictMode's double-mount a
single tab ended up holding three server WebSockets, and every asset_update was
delivered three times.

Detach handlers before closing, guard each handler against a superseded socket,
and cancel pending reconnect timers on teardown. Verified against the running
stack: /health reports websockets:1 for one open tab, down from 3.

Replaces the shape-only tests with coverage of the reconnect semantics.
2026-08-04 17:59:21 -04:00
9b86f41980 chore(beads): sync interactions.jsonl export 2026-06-02 02:34:02 -04:00
0c1fcb2a7e fix(globe): always prune entities so filtering to an empty theater clears the map
Some checks failed
Holocron Frontend CI / lint-and-test (push) Has been cancelled
The entity-prune step was guarded by currentAssets.size > 0, so selecting a
theater (or layer set) with no matching assets left stale markers on the globe.
Prune unconditionally and request a render when anything was removed.
2026-06-02 02:16:06 -04:00
ddcfee1507 feat(holocron): theater views — auto-discover MQTT theaters + human topic mappings
Server (server.cjs):
- subscribe to a discovery wildcard (<prefix>/+/assets/status/#) plus the base
  feed so every theater streams in automatically
- derive a theater id from each topic, stamp it on asset_update, track seen
  theaters, and expose GET /api/config/theaters

Frontend:
- stamp description.theater on incoming assets; filter the globe + Navigation
  by a selected theater
- theater <select> in the ControlPanel Navigation header (All + per-theater,
  live counts)
- new Settings → Topic Mapping tab: label/enable/add/remove mappings + adopt
  discovered theaters; persisted in user preferences (seeded with Test Feed +
  TFX-Baltics/CMED/EMED/NorthSea/Arctic/BlackSea/Gulf)
- utils/theaters.ts (+ tests): deriveTheaterFromTopic, filterAssetsByTheater,
  buildTheaterOptions
2026-06-02 02:09:57 -04:00
cad91be747 chore(beads): sync issues.jsonl export
Some checks are pending
Holocron Frontend CI / lint-and-test (push) Waiting to run
2026-06-02 02:04:18 -04:00
bcd3e6ddb3 feat(frontend): add MQTT theater discovery and per-theater views
Auto-discover theaters from <prefix>/<THEATER>/assets/status/# traffic,
stamp asset_update messages with a theater id, expose /api/config/theaters,
and add client-side TopicMapping prefs with seeded TFX exercise theaters.
2026-06-02 02:04:18 -04:00
6e1da5aa61 fix(deploy): disable ingress ssl-redirect (edge terminates TLS, ingress is HTTP-only) 2026-06-02 01:45:18 -04:00
a62a37895f feat(deploy): harden holocron chart — 2 replicas + PDB, read-only rootfs, required image.tag
- replicaCount 2 with RollingUpdate maxUnavailable=0 for zero-downtime rollouts
- PodDisruptionBudget (minAvailable 1)
- readOnlyRootFilesystem true with /tmp emptyDir
- image.tag now required (fails render with a clear message if unset)
- chart 0.1.0 -> 0.2.0
2026-06-02 01:40:13 -04:00
ac057f87c2 chore(deploy): update holocron chart maintainer email 2026-06-02 01:19:06 -04:00
79cc428495 chore(beads): sync interactions log 2026-06-02 01:03:15 -04:00
29e5bb3a8d docs(style): document R2/Farsight design system and align frontend neutral tokens
Some checks are pending
Holocron Frontend CI / lint-and-test (push) Waiting to run
- Add docs/STYLE.md describing the .settings/style reference, per-surface
  reproduction, and how holocron-frontend / holocron-sim docs map to it
- Link the design system from README.md and AGENTS.md
- Nudge holocron-frontend default-dark neutral tokens to reference values
  (bg-primary, text-primary/secondary/muted); keep tactical accents
2026-06-02 01:03:02 -04:00
ab72f2979c chore(gitignore): ignore Claude Code scheduler artifacts 2026-06-02 01:01:25 -04:00
Joshua Belke
fab7c7c020 docs(deploy): reconfigure deploy skill for holocron r2d2 target 2026-06-02 00:57:31 -04:00
Joshua Belke
f411ce9f45 feat(deploy): add holocron Helm chart for r2d2 (holocron.r2d2.office.ilab.zone) 2026-06-02 00:57:22 -04:00
c01a901817 docs(settings): add deploy skill doc and fumadocs/scalar style references 2026-06-02 00:55:02 -04:00
e93c7a64b1 feat(deploy): add holocron Helm chart with values overlay 2026-06-02 00:55:02 -04:00
ec7689fcc8 chore(beads): sync issues.jsonl export 2026-06-02 00:55:02 -04:00
881fb7c91e chore(gitignore): ignore local secrets (.env.local, kubeconfig, .devploy.env) 2026-06-02 00:55:02 -04:00
88ffa3cad5 refactor(compose): unify into single file with local/dev/demo profiles
Some checks failed
Holocron Frontend CI / lint-and-test (push) Has been cancelled
K8s is the production target — docker compose is local-only. Collapse the
three compose files (docker-compose.yml, .local.yml, .local-dev.yml) into a
single docker-compose.yml driven by profiles:

  local  → full stack in containers
  dev    → backing services only; frontend on host (npm run start:dev)
  demo   → synthetic MQTT publisher (composable with local or dev)

Make targets:
  make up      → --profile local --profile demo
  make up-dev  → --profile dev   --profile demo
  make up-bare → --profile local (no synthetic data)

All values (MQTT_TOPIC_PREFIX, MAPTILER_KEY, KEYCLOAK_*, host port mappings)
are env-driven with sensible local defaults. The same env contract is what
the K8s ConfigMap will inject in production.

Also:
- Bump frontend Dockerfile (local/dev) from node:18 → node:20-alpine.
  Vite 7 requires crypto.hash (Node 20.12+). Also bumps the test-publisher
  base image to node:20-alpine.
- Default host MQTT port moved to 1885 and frontend to 3002 (compose env
  defaults) to avoid common conflicts; both overridable via .env.

Verified:
- docker compose --profile local --profile demo config parses OK
- docker compose --profile dev   --profile demo config parses OK
- `make up` brings up 6 healthy containers
- curl localhost:7070/health → 200
- curl localhost:3002 → 200
- Test publisher streams UAV/SHIP/HELO/TANK positions on r2d2/holocron/...
- Browser screenshot confirms Cesium map rendering with live MQTT assets

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 09:57:46 -04:00
70a07a93c2 chore: rename holochron -> holocron and integrate R2D2 holocron components
Some checks are pending
Holocron Frontend CI / lint-and-test (push) Waiting to run
2026-05-28 09:31:30 -04:00
5c1e7fc17c chore: split holocron integration plan into beads 2026-05-24 18:50:36 -04:00
6e13f4d719 docs: plan holocron k8s and r2d2 integration 2026-05-24 18:48:36 -04:00
a53877235d bd init: initialize beads issue tracking 2026-05-22 19:08:02 -04:00
cb64a7c0ac feat: add map refresh button in Navigation panel
- Add refresh icon next to Navigation to reload map icons when symbols go missing
- CesiumViewer clears entities and re-syncs on refreshMapKey change
- Add RefreshIcon to PanelIcons, nav-header and nav-refresh-btn styles
- Ignore coverage directory in gitignore
2026-02-26 22:28:07 -05:00
24b09ee84a feat: add Tauri v2 desktop app support
- Install @tauri-apps/cli and initialize Tauri backend
- Add src-tauri/ with Rust backend, tauri.conf.json, capabilities
- Update Vite config for Tauri (strictPort, HMR, build targets)
- Add tauri:dev and tauri:build npm scripts
- Update README with Tauri usage and troubleshooting
2026-02-26 22:22:58 -05:00
2fb443fffd Code review improvements: logging, tests, position utils, CI, lint fixes
- Fix useWebSocket stale closure (onMessage ref)
- Fix useLayoutStore.getState() in render (App.tsx)
- Add ESLint + Prettier, logger utility
- Add unit tests: useWebSocket, useAssetTracking, position, geometry
- Extract position utils (src/utils/position.ts), deduplicate
- Extract geometry utils (src/utils/geometry.ts)
- Add CI workflow (.github/workflows/holochron-frontend-ci.yml)
- Add coverage reporting and thresholds
- Expand E2E tests (control panel, UXV drawer)
- Update README (ports 3333, file names)
- Add docs/ARCHITECTURE.md, CODE_REVIEW_FEEDBACK.md
- server.js -> server.cjs
2026-02-26 22:14:03 -05:00
dc43ca287f fix: Asset details Context should match symbol (Simulation for UXVs) 2026-02-26 21:06:02 -05:00
6a4fcf41de Add Storybook, Cypress, tests; migrate stores/hooks/utils to TypeScript 2026-02-26 20:44:43 -05:00
59c838e4db feat: UI improvements, feed info, and UXV Viewer updates
- Camera panel: raise z-index above asset details
- Video panel: remove redundant bottom bar, fix drag disappearing
- Video panel: add feed info popover (protocol, codec, resolution, host target)
- useDraggablePanel: use position:fixed, only set position on actual drag
- UXV Viewer: center title, improve spacing, add resizable height
- Streams: add FeedInfo metadata (protocol, codec, bitrate) from config
- Add InfoIcon to PanelIcons
2026-02-26 20:33:41 -05:00
16762f174b chore: TS/TSX-only frontend — remove JS/JSX duplicates, stop tracking mosquitto runtime
- Remove CesiumViewer.jsx, RightPanel.jsx, VideoPanel.jsx (use .tsx)
- Remove militarySymbol.js, streams.js (use .ts)
- Remove vite.config.js (use vite.config.ts)
- Stop tracking mosquitto/data and mosquitto/log (in .gitignore)
- Build and tests pass; ready for manual review
2026-02-20 10:23:24 -05:00
82237715fd chore: checkpoint — .settings, TS/TSX frontend, config, Makefile, verify-build 2026-02-20 10:22:01 -05:00
593b23bf73 Cesium React. 2025-12-17 14:26:16 +02:00
757ba8dace Adds cesium Demo code. 2025-12-11 17:40:12 +02:00
cbcbefc4d3 Initial commit 2025-12-11 13:38:06 +01:00
b8a2318890 Initialized variables 2025-12-11 12:31:21 +00:00
f09f95057e Fixing proxy (content type) 2024-05-24 12:21:07 +00:00
255456b390 Fixing Sonar code smells 2024-01-10 22:20:34 +00:00
12dee5d5be Update pipeline-stg.yml 2023-11-29 11:59:19 +00:00
bb042199ec Proxy bugfix 2023-11-29 11:47:00 +00:00
15fd244528 Periodical template update 2023-10-31 11:47:18 +01:00
876cf8af27 Merge branch 'pipelines_fix' into 'dev'
Pipelines fix

See merge request ihlc/teams/team-nightwatch/PlatformStream/project-templates/mvp-project-template!3
2023-01-17 18:35:48 +00:00
c9a8603969 Pipelines fix 2023-01-17 18:35:48 +00:00
Ashok
3907748c51 Merge branch 'pre-commit' into 'dev'
added pre-commit file

See merge request ihlc/teams/team-nightwatch/PlatformStream/project-templates/mvp-project-template!2
2022-10-13 19:09:47 +00:00
athakur
5b065a3476 added pre-commit file 2022-09-28 21:02:52 -04:00