* feat(backend): add LLM-powered feed enhancement
Add enhancement harness that fills feed item slots and
generates synthetic items via OpenRouter.
- LLM client with 30s timeout, reusable SDK instance
- Prompt builder with mini calendar and week overview
- arktype schema validation + JSON Schema for structured output
- Pure merge function with clock injection
- Defensive fallback in feed endpoint on enhancement failure
- Skips LLM call when no unfilled slots or no API key
Co-authored-by: Ona <no-reply@ona.com>
* refactor: move feed enhancement into UserSession
Move enhancement logic from HTTP handler into UserSession so the
transport layer has no knowledge of enhancement. UserSession.feed()
handles refresh, enhancement, and caching in one place.
- UserSession subscribes to engine updates and re-enhances eagerly
- Enhancement cache tracks source identity to prevent stale results
- UserSessionManager accepts config object with optional enhancer
- HTTP handler simplified to just call session.feed()
Co-authored-by: Ona <no-reply@ona.com>
* test: add schema sync tests for arktype/JSON Schema drift
Validates reference payloads against both the arktype schema
(parseEnhancementResult) and the OpenRouter JSON Schema structure.
Catches field additions/removals or type changes in either schema.
Co-authored-by: Ona <no-reply@ona.com>
* refactor: rename arktype schemas to match types
Co-authored-by: Ona <no-reply@ona.com>
---------
Co-authored-by: Ona <no-reply@ona.com>
* feat: add TimeOfDayEnhancer post-processor
Rule-based feed post-processor that reranks items
by time period, day type, and calendar proximity.
New package: @aris/feed-enhancers
Co-authored-by: Ona <no-reply@ona.com>
* fix: clamp boost values to [-1, 1]
Additive layers can exceed the documented range.
Co-authored-by: Ona <no-reply@ona.com>
* fix: use TimeRelevance consts instead of strings
Co-authored-by: Ona <no-reply@ona.com>
---------
Co-authored-by: Ona <no-reply@ona.com>
* feat: add generic CalDAV calendar data source
Add @aris/source-caldav package that fetches calendar events from any
CalDAV server via tsdav + ical.js.
- Supports Basic auth and OAuth via explicit authMethod discriminant
- serverUrl provided at construction time, not hardcoded
- Optional timeZone for correct local day boundaries
- Credentials cleared from memory after client login
- Failed calendar fetches logged, not silently dropped
- Login promise cached with retry on failure
Co-authored-by: Ona <no-reply@ona.com>
* fix: deduplicate concurrent fetchEvents calls
Co-authored-by: Ona <no-reply@ona.com>
* fix: timezone-aware signals, low-priority cancelled events
- computeSignals uses startOfDay(timeZone) for 'later today' boundary
- Cancelled events get urgency 0.1, excluded from context inProgress/nextEvent
Co-authored-by: Ona <no-reply@ona.com>
---------
Co-authored-by: Ona <no-reply@ona.com>
Replace tRPC location.update mutation with POST /api/location
using Hono route + requireSession middleware. Extract auth
types (AuthUser, AuthToken) into auth/session.ts. Inject
sessionManager via Hono context local to location handlers.
Co-authored-by: Ona <no-reply@ona.com>
- Expo SDK 54 / React Native 0.81 with expo-router
- Tailscale devcontainer feature for direct device connectivity
- Dev proxy for React Native DevTools access over Tailscale
- EAS build configuration for development/preview/production
- Ona automation for Expo dev server
Co-authored-by: Ona <no-reply@ona.com>
Add listActions() and executeAction() to FeedSource for write
operations back to external services. Actions use arktype schemas
for input validation via StandardSchemaV1.
- ActionDefinition type with optional input schema
- FeedEngine routes actions with existence and ID validation
- Source IDs use reverse-domain format (aris.location, aris.tfl)
- LocationSource: update-location action with schema validation
- TflSource: set-lines-of-interest action with lineId validation
- No-op implementations for sources without actions
Co-authored-by: Ona <no-reply@ona.com>
Add @aris/source-apple-calendar for fetching iCloud
calendar events via CalDAV using tsdav and ical.js.
- CalendarSource implements FeedSource with fetchItems
and fetchContext for downstream context
- CalendarCredentialProvider interface for token injection
- CalendarDAVClient interface for testability
- iCal parser extracts full event data including
attendees, alarms, organizer, and recurrence
- Priority based on event proximity to current time
Co-authored-by: Ona <no-reply@ona.com>
Manages per-user TflSource instances with individual line
configuration. Implements FeedSourceProvider so it can be
wired into FeedEngineService.
Adds TflSource.setLines() so line config can be mutated
in place, keeping engine references valid.
Also exports ITflApi from @aris/source-tfl for testability.
Co-authored-by: Ona <no-reply@ona.com>
- Add @trpc/server, @hono/trpc-server, zod dependencies
- Create tRPC context with BetterAuth session
- Create router with publicProcedure and protectedProcedure
- Mount tRPC at /trpc/* via Hono adapter
Co-authored-by: Ona <no-reply@ona.com>
- Add apps/aris-backend package with Hono server
- Add /health endpoint
- Add backend-spec.md with design decisions
Co-authored-by: Ona <no-reply@ona.com>
Migrates TFL package from old DataSource interface to new FeedSource
interface for use with FeedEngine.
Changes:
- Rename package from @aris/data-source-tfl to @aris/source-tfl
- Replace TflDataSource class with TflSource implementing FeedSource
- Add dependency on @aris/source-location for LocationKey
- Use normalized priority values (0-1) instead of arbitrary numbers
- Update tests for FeedSource interface
- Update README.md with new package name
Co-authored-by: Ona <no-reply@ona.com>
Implements FeedSource for WeatherKit API. Depends on location source,
provides weather context for downstream sources, and produces weather
feed items.
Co-authored-by: Ona <no-reply@ona.com>
Implements FeedSource interface. Accepts external location pushes,
provides context to downstream sources, does not produce feed items.
Supports configurable history size.
Co-authored-by: Ona <no-reply@ona.com>
Implements @aris/data-source-weatherkit for fetching weather data from
Apple WeatherKit REST API.
- WeatherKitDataSource class implementing DataSource interface
- Feed items: current, hourly, daily, and alerts
- Priority adjustment based on weather conditions and alert severity
- Unit conversion (metric/imperial)
- Response validation with arktype
- Test fixtures from real API responses
Co-authored-by: Ona <no-reply@ona.com>
TfL data source for tube, overground, and Elizabeth line alerts.
- Fetches line statuses and filters to minor/major delays and closures
- Sorts alerts by severity, then by proximity to user location
- Caches station data after first fetch
- Uses arktype for API response validation
- Supports API injection for testing
Co-authored-by: Ona <no-reply@ona.com>