Skip to content

Releases: azusachino/iroha

v0.5.1

Choose a tag to compare

@azusachino azusachino released this 29 Sep 09:10
944643c

Fixed

  • Compute average pace for Health Auto Export workouts from duration and distance, as the Apple Health importer does. Bump the import parser version so re-importing an HAE file replays retained evidence; at an unchanged version the import is skipped as already completed.
  • Show average heart rate next to pace on the Motion list and the public site's activity table for distance sports; runs previously showed only pace, so HAE runs displayed neither.
  • Redirect unknown paths on the public site to / instead of serving the app shell with a client-side 404.

Changed

  • Bump pgx to 5.11.0, vite to 8.3.1, bun to 1.4.2 (mise and images), golangci-lint to 2.14.0, rumdl to 0.2.77, and psycopg to 3.3.6.

v0.5.0

Choose a tag to compare

@azusachino azusachino released this 29 Sep 08:33
9820152

Added

  • Add the single-owner login from ADR-0008: a one-time setup screen, Argon2id password login, server-side sessions in an HttpOnly Secure SameSite=Lax cookie, and CSRF tokens on state-changing
    requests. Every private /api/v1 route now requires the owner session.
  • Add passkeys (ADR-0008 item 6): username-less passkey sign-in, and add/rename/remove under Account settings → Security with a password re-confirmation. Enabled by IROHA_WEBAUTHN_RP_ID and
    IROHA_WEBAUTHN_ORIGINS (migration 00024).
  • Replace the sign-in and setup screens with a Kite-style card, move log out into a header user menu on every page, and add a display name (migration 00023).
  • Rebuild Admin as tabs: System (versions, schema, storage, cache), Sources (per-source status and sync; replaces the Sources strip on Today and Overview), Jobs (pause/resume and run schedules now,
    retry failed and cancel queued jobs), Imports (browser upload, history, reprocess), and Intake tokens.
  • Add HAE intake-token management to the Admin page, and the break-glass iroha-admin password reset.
  • Rate-limit login and setup (10/min) and HAE intake (30/min) per client, with per-credential intake quotas (120 requests/hour, 512 MiB/day). Behind a proxy in IROHA_TRUSTED_PROXY_CIDRS, the client
    is taken from Cf-Connecting-Ip.
  • Run the web image as a non-root user on port 8080, with the Caddy admin API off and security headers set.
  • Serve the public site's data live from an anonymous, rate-limited /public/v1 API (summary, activities, routes, meta, and per-activity detail), cached up to 24 hours and rebuilt when activities
    change. The public site is now a client shell in its own iroha-public-site image; the export and builder jobs are retired, and iroha-job disables the projection_refresh schedule when no export
    directory is configured.
  • Scripts that call the private API log in with IROHA_USERNAME/IROHA_PASSWORD; the release-candidate gate creates a throwaway owner.
  • Add native Health Auto Export (HAE) Format v2 JSON parser and provider adapter for continuous, automated daily health data intake (KindHealthAutoExport = "health_auto_export").
  • Support sparse metric ingestion: unconfigured metrics are omitted safely; sleep durations in fractional hours are converted to integer seconds; non-empty metric units defensively default to conform
    to database check constraints.
  • Parse GPS route trackpoints and continuous heart rate samplings directly from HAE workout payloads into canonical activity observations.
  • Expand POST /api/v1/intake/health request body limit to 10 MiB to accommodate high-resolution GPS tracks and workout vital series.
  • Add setup documentation (docs/health-auto-export-setup.md) with detailed user stories, iOS/watchOS export settings, and troubleshooting instructions.
  • Add architecture decision record ADR-0008 documenting the two-tier ingestion model, the required intake credential, and bounded replacement
    semantics.
  • Replace the legacy schema boundary with a fresh SQLx-managed schema through migration 00025. This is a cut-over release: raw evidence is replayed into the new schema; no legacy-schema migration or
    Goose adoption is provided.
  • Replay the complete 2026-09-08 Apple Health export without destructive purges, preserving source receipts, interpretation history, canonical activities, daily health, and sleep projections.
  • Add scheduled AniList/Bangumi sync runs, agent-applied matching decisions, and source-aware cockpit attention.
  • Add expense accounts, linked and unlinked refunds, revision-backed consistent reads, report evidence status, connection actions, restored agent CLI parity, and an honest sanitized public exporter
    boundary.

Changed

  • Require a dedicated intake credential on every POST /api/v1/intake/health request (ADR-0008). Each device gets its own revocable credential; only a SHA-256 verifier of the iroha_hae_-prefixed
    token is stored (migration 00021). Intake fails closed with 503 until iroha-admin intake-token issue issues one, and the credential name sets the source instance.
  • Label Health Auto Export coverage in the effective timezone (IROHA_TIMEZONE) and widen it to whole device-local days. Previously every HAE import failed on a server running in UTC.
  • Accept only Health Auto Export Format v2: intake rejects workouts without an id or with an offset-less start time, and imports fail loudly on malformed timestamps or unsummarized sleep instead of
    silently dropping data.
  • Fix HAE distance conversion (only the first point of a miles metric was converted), convert metres, and convert workout energy reported in kJ.
  • Rewrite the Health Auto Export setup guide and add a reference page for HAE settings and payloads.
  • Delete raw file bytes after a retention window: a daily raw_file_purge job removes them 7 days after upload (30 for failed imports) and sets tb_raw_files.purged_at (migration 00025); the row and
    its sha256 stay. IROHA_RAW_RETENTION_DAYS=0 disables it. Re-uploading identical bytes restores a purged file.
  • Report Health Auto Export metrics Iroha does not map: the upload's health coverage becomes partial and lists them, with data-point counts, under scope.unsupported_metrics.
  • Isolate DB-backed Go tests: they refuse any database not named iroha_test* (or declared throwaway), and make test-integration recreates iroha_test and runs every module's integration tests.

Fixed

  • Admin and Account-settings tabs now follow the WAI-ARIA tabs keyboard pattern (arrow, Home and End keys, roving tabindex).
  • A manual run of raw_file_purge with IROHA_RAW_RETENTION_DAYS=0 no longer purges every completed import.

Removed

  • Remove five of the six design languages (atlas, field-journal, phenology, cadence, archive), their ambient backgrounds, the design compositions, the language picker, and both /design workbench
    pages. Grapher is the only design language.
  • Remove the dead iOS Shortcuts receiver (apple_health_shortcut.go, test fixture, and setup documentation) in favor of native Health Auto Export background sync.

Verification

  • make release-candidate passed against an isolated PostGIS database: migrations 1–20, all Go integration packages, seeded API/performance checks, production web build, readiness, and the 6-theme ×
    light/dark × 3-route browser matrix.
  • make check and make test-integration pass cleanly with full coverage of the new Health Auto Export bounded replacement ingestion.

v0.4.5

Choose a tag to compare

@azusachino azusachino released this 28 Aug 14:58
1cd376d

Added

  • Give Atlas an ambient WebGL background: a flat survey chart of scattered teal "dust" points and larger amber legend markers with a handful of faint triangulation lines between them, drifting at a
    near-imperceptible compass-card rotation. This is the first slice of a per-theme ambient layer (infra: packages/iroha-shared/src/theme-ui/ambient/) mounted once at the root layout behind
    everything — every data tile already paints an opaque --tile-surface, so the canvas only shows through chrome and empty space and never touches data legibility. A theme with no registered scene
    (Grapher, and the four not yet built) renders nothing, continuing Grapher's established plainest-of-six identity. Reduced motion is a state contract, not a slower loop: a preferring client gets
    exactly one rendered frame and requestAnimationFrame is never scheduled. Adds three (core entrypoint only — no loaders/postprocessing) as a lazily-imported dependency, dynamically loaded from
    inside the host component so it never lands on the initial critical-path bundle: production build grew from 3.5M to 4.0M on disk, entirely inside one new lazy chunk (518 kB raw / 128 kB gzip, absent
    from index.html's eager references) that only fetches once the ambient layer actually needs to build a scene. This is the "recorded seam justification and bundle comparison" the v0.4.4 plan's
    decision #4 asked for before any Three.js dependency — approved for this pass as a deliberate personal-project "try the fancy stuff" call, not a user-problem fix.
  • Give Field Journal, Phenology, Cadence, and Archive their own ambient WebGL scene, completing the per-theme ambient layer Atlas started above. Field Journal: two columns of ruled margin tick-marks
    drifting downward and wrapping, a bullet-journal's date/note column down each page edge. Phenology: a phase wheel — a ring of dial ticks with four season markers hubbed to the center by spokes, the
    whole wheel slowly rotating, the one scene where rotation is the primary motion rather than a near-imperceptible touch. Cadence: a level-meter rack of 24 independently pulsing vertical bars, each on
    a phase/frequency derived deterministically from its own index, never driven by any audio input — matching Cadence's own lens copy ("do not pretend expense data is audio"). Archive: a card-catalog
    drawer sweep — a row of vertical card-edge ticks whose brightness travels left to right and wraps, fading toward --surface rather than to black so a dim card reads as "unlit," not "gone." Every
    scene was verified via visual-check.mjs's CANVAS_SELECTOR pixel-readback mode rather than a literal screenshot, since headless Chromium's software compositor doesn't reliably paint WebGL canvas
    content into page.screenshot() even when the canvas genuinely has drawn content.
  • Add CoverageBars.svelte, a real DOM/CSS bar list for daily-health metrics with a per-metric icon and label, replacing an ECharts chart that couldn't host a Svelte icon component inside its own
    canvas-rendered axis labels. Bars show the metric's real value; for the 4 of 11 tracked metrics with a genuine, citable, general-adult-population reference range (resting HR: American Heart
    Association; SpO₂ avg/min: clinical pulse-oximetry consensus; respiratory rate: American Lung Association — see domain/health-metric-ranges.ts for exact sourcing), the bar is positioned within
    that range and switches to the theme's own --danger color when the value falls outside it. The other 7 metrics (steps, distance, flights, walking HR, HRV, VO₂max, body mass) intentionally get no
    range — none of them has one that's both official and general-population (steps' "10,000" is a popularized proxy, not WHO's actual activity-minutes-based guidance; HRV and VO₂max need age/sex
    percentile bands this app's data model doesn't carry; body mass needs height to mean anything) — and a fabricated range would be worse than none.
  • Plot a real month-over-month line trend for every daily-health metric with data in the twelve-month window ("Twelve-month trends"), replacing a single "Observed days" line that only ever measured
    how many days had any value, never what the value was. Required a small backend addition: the monthly report series endpoint was already computing per-metric averages for every month but
    discarding them down to observed_days alone when reducing into a trend point.
  • Add per-sport, per-expense-category, and per-health-metric icons to SportBadge, ExpenseLedger, every theme's Activities.svelte table, and a new IconLegend strip above the Movement and
    Expenses reports charts — icons are colored by a stable per-identity color map (domain/*-colors.ts, keyed by identity rather than array position) instead of an order-dependent categorical palette,
    so a metric or category's color no longer changes just because the API happened to return it in a different order.

Changed

  • Give Atlas its own semantic status colors and no-data copy voice instead of sharing the app-wide neon danger/positive/warning set and the generic "No records" fallback with all six languages. Danger
    moves to a clay/terracotta already in Atlas's own --ring-exercise family; positive/warning tie directly to the map's own water/brass accents (--accent/--accent-2). Report cards' zero-data
    fallback now reads "Uncharted", scoped to Atlas's own Reports.svelte.
  • Give Field Journal, Phenology, Cadence, and Archive their own semantic status colors and no-data copy voice, completing the pass Atlas started above. Field Journal: a ballpoint-red danger and
    highlighter-amber warning read as bullet-journal ink. Phenology: a wilted/dried-bloom danger and a growth-green positive. Cadence: a mixing-console clip-light danger. Archive: a
    due-date/withdrawn-stamp danger and a certification-gold positive. Each theme's own "no records" fallback: "No record" (Field Journal, already in place), "Dormant" (Phenology), "Silence" (Cadence),
    "Uncatalogued" (Archive).
  • Change the daily-health panel's bars to show each metric's real value instead of an observed_days / period_days coverage percent — coverage reads as near-100% noise for anything that syncs daily
    (HRV) and never actually said what the value was. Coverage moves into the row's tooltip instead. Also fixes the panel's unit="%" label, stale now that rows carry mixed real units (km, bpm, ms, %,
    ...) instead of one shared percentage.
  • Give Admin a real operational question instead of a generic heading, per the v0.4.4 scorecard's own follow-up note ("give app-only Admin a specific operational question and compact utility-header
    contract"). Replace the "Admin" hero heading with "What needs attention?" at the compact --grapher-utility-title-size scale Motion/Night/Patterns/Library already use (Admin's own heading was still
    at full editorial hero size). Swap the static "Metric catalog" status card for a "Needs attention" card surfacing the failed-job count — the metric catalog total is still shown in the Metric
    definitions panel header, just no longer duplicated as its own status tile that didn't answer the page's question.
  • Give every registered design language real ownership of the persistent app-bar/nav shell instead of leaving it fully host-owned and identical regardless of theme. Shell.svelte's contract
    (ShellThemeProps) now accepts brand/nav/actions snippets from the host, and each of the six languages restyles that shared markup into its own header via scoped selectors — a dashed
    map-legend for Atlas, flat axis-tick tabs for Grapher, a dotted/wavy-underline masthead for Field Journal, a phase-dot pill for Phenology, a rack-style "mixing console" for Cadence, and a
    card-catalog drawer strip for Archive — without duplicating the underlying interactive elements, so the existing audited focus order, tap-target sizes, and accessible names carry over unchanged.
  • Give every language its own --tile-surface/--tile-shadow (every data tile app-wide reads these) and its own glyph for the shared "no records" empty-state mark, instead of both being identical
    across all six and differing only by accent color. Atlas's active nav item also gets a small triangle marker ahead of the label, borrowed from cartography's own convention for "the most important
    point." The empty-state glyphs are sourced from each theme's real-world reference rather than invented: bullet-journal notation for Field Journal, a coordinate crosshair for Atlas, a phase-wheel
    glyph for Phenology, paused-channel bars for Cadence, and the empty-set symbol for Archive.
  • Give Field Journal and Phenology's shell root the font-family each already declared via --font-serif but never actually applied outside a few hand-styled headings, so their whole page reads in
    the theme's typeface rather than falling back to the shared default sans. Give Atlas its own monospace stack instead of reusing Cadence's byte-identical one. Add --body-leading and
    --heading-tracking, consumed by body/h1/h2, so line-height and letter-spacing also vary per language.
  • Fix the language-switch cross-fade, which was silently inert: its wrapper was display: contents, a box-less display mode that opacity/transform transitions cannot render anything on. A distinct
    motion signature per language (lateral pan, overshoot bloom, stamp scale, etc.) was tried and read as over-designed in practice, so the fix keeps one shared plain fade for all six — a
    full-composition swap should stay calm regardless of which language is switching in. Each language still gets its own --motion-micro/--motion-quick-state hover/press timing.
  • Give the shared sport/source badges (SportBadge, SourceBadge) each theme's own corner radius via the existing --radius token instead of a hardcoded pill shape — the only two shared controls
    with no per-language styling; every other shared control (SelectControl, MonthNavigator, `Per...
Read more

v0.4.4

Choose a tag to compare

@azusachino azusachino released this 24 Aug 05:27
6ac3a5b

Added

  • Add executable private-route checks for skip-link/main-landmark integrity, heading order, compact visual/focus order, 24x24px standalone controls, and semantic table drill-down controls across the
    existing language, mode, motion, and mobile viewport matrix.
  • Add a seeded representative UI/UX scorecard covering Today, Overview, Patterns, Metrics, To-go, and Admin without retaining private screenshots or payloads.
  • Introduce a liquid-glass material (backdrop blur + saturate + a layered inset highlight) for floating chrome only — the app bar, primary-nav pill, command palette, and the Domains/Analyze/More and
    month-picker popovers — with a prefers-reduced-transparency fallback to an opaque surface on every surface it touches. Data tiles and route content stay opaque.
  • Add a named --motion-* token set (micro, quick-state, data-update, language-switch) in the shared theme package and apply it across four felt vertical slices: LoadingBoundary's loading →
    ready arrival transition, the shared ring gauges' (and three per-language inline rings') value-change sweep, a cross-fade on design-language switching, and a reveal transition on the
    Domains/Analyze/More navigation popover (@starting-style + transition-behavior: allow-discrete, since it lives inside a native <details>).
  • Animate Grapher's Today headline numbers (Move, Exercise, Steps, sleep efficiency) on change via a new shared AnimatedNumber primitive (svelte/motion's tweened), jumping instead of tweening
    across null/absent-data transitions.
  • Add make motion-tokens-check (wired into make check): fails if a var(--motion-*) reference has no matching definition in the shared theme package.

Changed

  • Give Grapher's frequently used Motion, Night, Patterns, and Library routes a compact utility-title scale while preserving the editorial Today and Overview hierarchy.
  • Require an explicit Metrics dimension selection instead of guessing the first catalog value; preserve explicit empty selections and load catalog/series state through the shared latest-request-wins
    async resource.
  • Replace mouse-only Patterns table rows in all six design languages with native period buttons that provide keyboard-equivalent evidence navigation.
  • Give every design language a real base typeface instead of falling back to system-ui — five of six languages, and the base document text in both the private cockpit and the public site, had no
    --font-sans of their own.
  • List a period selector's month dropdown newest-first, matching the year dropdown's own long-standing convention — every consumer (Motion, Overview, Expenses, Reports, Metrics, Night) listed January
    first regardless of which month was actually most recent.
  • Narrow the global prefers-reduced-motion rule so it stops decorative/infinite loops without crushing every transition duration to near-zero via !important, which foreclosed any deliberate
    reduced-motion result a component might need.

Fixed

  • Add a first-focus skip link and one canonical focusable main landmark, align compact header DOM and visual order, raise audited standalone controls to the product's 24x24px floor, and restore Today
    and Overview's H1-first outline.
  • Give empty Today a Jump to latest recorded day action and defer its URL synchronization until SvelteKit's router is initialized.
  • Normalize the API's null dimension list for canonical metrics so dimensionless series such as Steps render instead of failing after catalog load.
  • Restore the desktop-centered primary navigation without reopening the compact focus-order fix above — the DOM reorder that fixed 375px focus order had also pushed the nav flush right on desktop; the
    compact "own full row" treatment now targets the app-bar actions instead of the nav, so DOM order still matches visual order at every width.
  • Retint dark mode's tile shadow to match the background hue (light mode already did this), and fix a popover shadow that referenced an undefined --shadow custom property and always silently fell
    back to a flat black default regardless of theme.
  • Stop the Overview route-summaries table from blowing out of its card and off the page — a pre-existing min-width: auto grid-overflow bug — and relax its flat 34rem minimum width so the actual
    content fits without forcing an unnecessary horizontal scroll in a half-width dashboard card.

v0.4.3

Choose a tag to compare

@azusachino azusachino released this 16 Aug 05:56
b80848f

Changed

  • Move the Bangumi->MAL->AniList cross-provider media resolution bridge from two ConfigMap-mounted JSON files (rebuilt and redeployed manually, no queryability) to a tb_media_ref_bridge Postgres table (migration 00012_media_ref_bridge.sql). iroha-job still loads both hops into an in-memory map at startup; refresh is now a manual, on-demand media_bridge_refresh job handled by the already-running worker (no new pod or scheduled job), triggered from a new "Media bridge" button on /to-go next to the existing AniList/Bangumi sync actions.
  • scripts/build_media_bridge.py now upserts into Postgres via psycopg instead of writing JSON files (still available for local dev convenience).

v0.4.2

Choose a tag to compare

@azusachino azusachino released this 16 Aug 04:23
825d505

Added

  • Add scripts/paypay_import.py, a PayPay transaction-history CSV importer that creates canonical expenses idempotently (safe to re-run against overlapping exports), excluding balance top-ups, points, PayPay's spare-change auto-invest, received money, and refunds from spend totals.
  • Complete the frontend modularization follow-up from issue #53: extract library/patterns route business logic into co-located .svelte.ts state modules, and reorganize packages/iroha-shared/src's 42 flat files into domain subdirectories (view-contracts/, domain/, format/, components/, theme/).
  • Document the month/year/lifetime scope model as a hard rule in AGENTS.md.

Fixed

  • Fix Expenses' "All months" period option, which was reachable but silently did nothing; the category/currency totals charts also needed their metric-series aggregation grain switched to match the selected scope width so a year view reflects the real year-wide total instead of only its first month.
  • Fix BarChart's horizontal-orientation grid right margin clipping longer formatted value labels (e.g. a JPY total with a thousands separator).
  • Fix ops/images/Containerfile.server's export-public stage missing tzdata, needed for the CronJob's Asia/Tokyo schedule check.

v0.4.1 — Cache-correct report reads

Choose a tag to compare

@azusachino azusachino released this 15 Aug 14:49
4f47e7b

Added

  • Add one backend-neutral runtime cache module with Postgres, Valkey, and explicit none backends; production process-memory caching is not used.
  • Add complete response caching for monthly and twelve-month reports under the read_reports namespace.
  • Add bounded Postgres cache cleanup for expired and superseded-generation entries, including hourly worker maintenance.
  • Add a deterministic large-fixture release performance gate for cold canonical reads, cache hits, mutation freshness, and cache retention.
  • Add canonical media provider history and dated AniList activity import, keeping exact consumption events separate from provider state changes.
  • Add a distinct Book media family, separate from manga and light novels, ahead of future book-provider adapters.
  • Add apps/iroha-web/src/lib/asyncResource.svelte.ts, one shared reactive resource primitive (data/loading/error/sticky-ready) that every route's LoadingBoundary usage now goes through instead of
    a hand-rolled loading/error/request-counter triple per route.

Changed

  • Make cache identity include the server's effective timezone, so omitted and explicit default-timezone requests cannot collide with another interpretation.
  • Make cache population generation-safe and make successful canonical mutations invalidate their dependent namespaces after commit.
  • Make known invalidation failures bypass affected cache namespaces until a later invalidation succeeds.
  • Keep direct expense records live and canonical while caching derived metric and report representations.
  • Make media library filters, current-status totals, completion-year selection, charts, Today updates, and detail history use the same canonical scope.
  • Preserve provider date precision and source basis; connector snapshots never become exact daily consumption sessions.
  • Make period navigation (year/month selectors, including arrow-key shifts) clamp to the real imported data range instead of the current date.
  • Consolidate each theme's page-shell width into a single --shell-width custom property instead of a literal duplicated across the base rule, the mobile breakpoint, and (for three themes) the footer
    padding calc.

Fixed

  • Refresh expense metric/report reads after expense create, replace, and delete.
  • Refresh activity route representations after geocode changes and media/report representations after media resolution changes.
  • Correct media detail evidence to distinguish exact events from dated provider updates and hide internal observation snapshots.
  • Normalize Grapher media-detail titles to a regular responsive record-heading scale instead of a landing-page hero scale.
  • Fix Grapher Activities/Dashboard and the shared movement-series chart replacing their whole DOM structure with a status message on every data refetch (period/filter change) instead of only the first
    load; the same non-sticky-ready bug was live on Motion, Night, Patterns, and Overview and is now structurally prevented by LoadingBoundary taking an async resource directly rather than
    caller-computed loading/ready booleans.
  • Fix the To-go page's oversized headline crowding the actual task list on what's meant to be a short, fast, daily-use page.

v0.4.0

Choose a tag to compare

@azusachino azusachino released this 14 Aug 11:30
4cef74c

Changelog

Added

  • Add the canonical private expense ledger with idempotent create, list, detail, replacement, and tombstone-delete APIs.
  • Add synchronous monthly reports with typed movement, sleep, daily health, media, and expense sections.
  • Add the general local CLI transport and expense/report commands, plus private /expenses and /reports cockpit pages.

Changed

  • Keep expenses and reports out of the sanitized public export; add a serialized projection regression test for that boundary.
  • Adopt requests for the Python CLI transport and lock its dependencies with uv.
  • Document the v0.4 local-agent boundary: OCR may happen outside Iroha, while Iroha validates and stores canonical JSON deterministically.
  • Move canonical theme identities, route compositions, charts, controls, and adopted design compositions into @iroha/shared; both the private cockpit and public design workbench consume the same assets.
  • Make monthly reports chart-first with twelve-month comparison, truthful empty/partial months, canonical units, provenance, and exact evidence below the visual summary.
  • Add the v0.4 release-candidate contract gates: deterministic seeded integration/runtime checks, six-language light/dark browser coverage, mobile overflow/reduced-motion checks, and the shared-theme boundary check.
  • Harden compact navigation and shared theme layouts at 320, 375, 390, and 414 CSS pixels without changing the private/public data boundary.

See CHANGELOG.md for the full project history.

v0.3.1

Choose a tag to compare

@azusachino azusachino released this 12 Aug 04:39
9b8fc7b

What's Changed

Full Changelog: v0.3.0...v0.3.1

iroha v0.3.0

Choose a tag to compare

@azusachino azusachino released this 11 Aug 13:28
68e726d

iroha 0.3.0 closes the UX tuning release with six themed views, shared period selection and URL-persisted date state across Patterns/Motion/Night, corrected sleep/media overview totals, lazy night loading, aligned app branding, and the 0.4 expense-ledger roadmap.

Validation: make validate, public-site typecheck/build, Bun audits, six govulncheck scans, and merged CI make check.

Full details: https://github.com/azusachino/iroha/blob/v0.3.0/CHANGELOG.md#030