Reference

Contributing

Bug reports, fixes and new features are welcome. TripLibre is small enough to read in an afternoon, and most of the interesting logic lives in a package you can test without a phone.

Development setup

git clone https://github.com/zyang91/TripLibre.git
cd TripLibre
brew install xcodegen swiftlint swiftformat
make test     # core tests, no simulator needed
make sim      # run the app with demo data
make lint     # docs JS/CSS/HTML + accessibility, Markdown, Python, Swift (needs node + ruff)

Changing Swift? make swift-lint runs the same SwiftLint and SwiftFormat checks as CI. SwiftLint only enforces correctness and VoiceOver rules (.swiftlint.yml); violations that already existed are listed in .swiftlint-baseline.json, so only new ones fail. If you fix old ones, run make swiftlint-baseline and commit the updated file. SwiftFormat checks whitespace only (.swiftformat) and never rewrites files in CI.

Changing the docs site? Run npm run lint (or npm run lint:fix) before opening a PR. The HTML check includes html-validate's accessibility rules: images need alt, buttons need a type and an accessible name, and aria-label only goes on elements that can carry one. npm run a11y then loads every page in Chromium, in light and dark theme, and runs axe-core's WCAG 2.1 AA rules against the finished page, including colour contrast and the navigation docs.js builds (first run: npx playwright install chromium).

Where to make a change

You want to…Look in
Improve visit / trip / mode detectionInference/ and InferenceConfig; add a fixture scenario in Tests/HHTCoreTests/InferenceTests.swift
Add a correctionEditing/EditService.swift; always write audit_log and set user_status
Change the schemaDatabase/Schema.swift; add a new migration, never edit an old one
Add a metricAnalytics/MobilityMetrics.swift, mirrored in analysis/hht.py and docs/analytics.md
Add an export columnExport/Exporter.swift; the Python contract check (make export-check) must still pass
Change background collectionApp/Location/LocationCollector.swift; test on a real device, the simulator can't reproduce it
Change a Home Screen widgetViews in Widgets/; data in Widget/WidgetSnapshot.swift (bump currentVersion if its shape changes, and extend WidgetSnapshotTests)
Change the UIApp/Screens/, styling in App/Support/Theme.swift
Edit these docsdocs/triplibre/docs/*.html; navigation is in docs/assets/docs.js. See Documentation below

Ground rules

Proposing an inference test case

Wrong visits, trips and modes are the most useful reports, and the hardest to share safely: the evidence is your location history. Please never attach an export, a travel.sqlite file, a GPX track or screenshots of your map to a public issue. Describe the shape of the problem instead, so it can be rebuilt as a synthetic fixture:

  1. Describe what happened"Walked 600 m between two buildings, stayed 40 min, took a rideshare for 12 min." Times can be relative ("+0:40"); no addresses or coordinates needed.
  2. Describe what TripLibre recorded"One 2 h visit, no trip" or "the rideshare was labelled subway". Include the mode confidence and whether the trip showed a gap, if you can see them.
  3. Add the signal, not the placeIf you're comfortable, read from your own export: roughly how often fixes arrived, their accuracy (h_accuracy), speeds, any silences longer than a couple of minutes, and the CoreMotion activity during the problem.
  4. Write or request the fixtureTest cases are written with the synthetic Trajectory builder in Packages/HHTCore/Tests/HHTCoreTests/Fixtures.swift, using its fixed Philadelphia landmarks, and go in CalibrationTests.swift or InferenceTests.swift. A good fixture fails on the current engine and states the expected visits, trips and modes.

If a real trace is truly needed, share it privately with the maintainer, and only after shifting it far from where it happened, rotating it and offsetting the times. Even then, home and work can sometimes be recovered from the pattern. Accuracy measurements on real data are summarised in aggregate only; see Validation.

Documentation

Before opening a pull request

  1. Run the checks CI runs
    make ci
  2. Regenerate the project if you touched project.yml: make project, and commit HHT.xcodeproj. CI fails if they differ.
  3. Update docs: the markdown specs in docs/*.md and these pages if behaviour changed.
  4. Open the PR against main with a short description of what changed and why.

Releases

Released versions are listed in CHANGELOG.md and on GitHub Releases. Each GitHub release is archived on Zenodo under one concept DOI, 10.5281/zenodo.23307589. Before tagging vX.Y.Z, set the same version in all three places, or the archive will be labelled with the old one:

Then add a section to CHANGELOG.md.

Reporting issues

Use the issue templates for bugs and feature requests. For a wrong trip or visit, follow proposing an inference test case above. Don't attach raw exports: they contain your location history. Security problems go through SECURITY.md, not public issues.

Everyone participating is expected to follow the Code of Conduct.

License

TripLibre is released under the Apache License 2.0. Contributions are accepted under the same license. The repository has no NOTICE file; if a contribution brings in third-party code that requires one, add it in the same pull request.