{"id":36942178,"url":"https://github.com/radupana/openweight","last_synced_at":"2026-03-01T21:03:43.950Z","repository":{"id":326956794,"uuid":"1106564834","full_name":"radupana/openweight","owner":"radupana","description":"Open standard for exchanging strength-training programs, workouts, and logs between fitness apps","archived":false,"fork":false,"pushed_at":"2026-01-13T13:58:09.000Z","size":315,"stargazers_count":1,"open_issues_count":12,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-13T21:17:32.636Z","etag":null,"topics":["fitness","json","schema","specification","standard","strength-training"],"latest_commit_sha":null,"homepage":"http://openweight.dev/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/radupana.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-29T14:03:12.000Z","updated_at":"2025-12-07T20:45:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/radupana/openweight","commit_stats":null,"previous_names":["radupana/openweight"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/radupana/openweight","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radupana%2Fopenweight","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radupana%2Fopenweight/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radupana%2Fopenweight/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radupana%2Fopenweight/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/radupana","download_url":"https://codeload.github.com/radupana/openweight/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radupana%2Fopenweight/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29980773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fitness","json","schema","specification","standard","strength-training"],"created_at":"2026-01-13T10:59:44.266Z","updated_at":"2026-03-01T21:03:43.945Z","avatar_url":"https://github.com/radupana.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# openweight\n\n**Open data format for strength training.**\n\nYour training data belongs to you, not to any one app.\n\n## Why openweight?\n\nStrength training data is trapped in silos. Each app has its own export format, its own idea of what a \"workout\"\nor \"set\" means, and no reliable way to move your history between tools. When you switch apps, you lose years of data.\nWhen\nan app shuts down, your history disappears.\n\n**openweight** is a vendor-neutral JSON format that solves this:\n\n- **Export from one app, import to another** — no more lock-in\n- **Archive your training history** — in a format that will outlast any app\n- **Analyze with any tool** — standard JSON that works everywhere\n\n## Core Schemas\n\n| Schema              | Purpose                                                            |\n|---------------------|--------------------------------------------------------------------|\n| **WorkoutLog**      | Completed workouts with actual reps, weight, RPE                   |\n| **WorkoutTemplate** | Planned workouts with targets (reps, percentage-based weight, RPE) |\n| **Program**         | Multi-week training programs composed of templates                 |\n| **LifterProfile**   | Athlete data, PRs, 1RMs, height, bodyweight history                |\n\n## Quick Example\n\n```json\n{\n  \"$schema\": \"https://openweight.dev/schemas/workout-log.schema.json\",\n  \"date\": \"2024-01-15T09:00:00Z\",\n  \"exercises\": [\n    {\n      \"exercise\": {\n        \"name\": \"Squat\"\n      },\n      \"sets\": [\n        {\n          \"reps\": 5,\n          \"weight\": 140,\n          \"unit\": \"kg\",\n          \"rpe\": 7\n        },\n        {\n          \"reps\": 5,\n          \"weight\": 140,\n          \"unit\": \"kg\",\n          \"rpe\": 8\n        },\n        {\n          \"reps\": 5,\n          \"weight\": 140,\n          \"unit\": \"kg\",\n          \"rpe\": 8.5\n        }\n      ]\n    }\n  ]\n}\n```\n\n## Getting Started\n\n**TypeScript/JavaScript:**\n\n```bash\nnpm install @openweight/sdk\n```\n\n```typescript\nimport {parseWorkoutLog, isValidWorkoutLog} from '@openweight/sdk';\n\nconst log = parseWorkoutLog(jsonString);\nconsole.log(log.exercises[0].exercise.name); // \"Squat\"\n```\n\n**Kotlin/JVM:**\n\n```kotlin\nimplementation(\"io.github.radupana:openweight-sdk:0.4.0\")\n```\n\n```kotlin\nval log = parseWorkoutLog(jsonString)\nprintln(log.exercises[0].exercise.name) // \"Squat\"\n```\n\n## CLI\n\n### Convert your workout data\n\nExport your data from your app, then convert it to openweight JSON:\n\n**From Strong:**\n1. Strong app → Settings → Export Workout Data → CSV\n2. Run:\n```bash\nnpx @openweight/cli convert --weight-unit kg strong.csv -o workouts.json --pretty\n```\n\n**From Hevy:**\n1. Hevy app → Profile → Settings → Export \u0026 Import Data\n2. Run:\n```bash\nnpx @openweight/cli convert hevy.csv -o workouts.json --pretty\n```\n\nThe source format is auto-detected from CSV headers. Use `--format strong` or `--format hevy` to override.\n\n### Validate openweight files\n\n```bash\n# Auto-detects schema type (workout-log, program, etc.)\nnpx @openweight/cli validate workout.json\n\n# Explicit schema type\nnpx @openweight/cli validate --schema workout-log workout.json\n```\n\n### AI-Assisted Conversion\n\nWhen the converter encounters unknown CSV columns or exercise names, you can use `--ai-assist` to let an LLM help map them:\n\n```bash\n# Requires OPENAI_API_KEY environment variable\nnpx @openweight/cli convert export.csv --ai-assist --pretty\n\n# Or use a local model via Ollama\nOPENWEIGHT_AI_URL=http://localhost:11434/v1 npx @openweight/cli convert export.csv --ai-assist\n```\n\nAI suggestions are shown for your approval before being applied. Confirmed mappings are cached locally (`~/.openweight/mapping-cache.json`) so the same columns/exercises resolve instantly next time.\n\n### All CLI options\n\n```\nopenweight convert \u003cfile\u003e\n  -f, --format \u003cformat\u003e       Source format: strong, hevy (auto-detected)\n  -u, --weight-unit \u003cunit\u003e    Weight unit: kg or lb (required for Strong)\n  -o, --output \u003cfile\u003e         Output file (default: stdout)\n  --pretty                    Pretty-print JSON\n  --report                    Print conversion report to stderr\n  --ai-assist                 Use AI to map unknown columns and exercise names\n  --ai-model \u003cmodel\u003e          AI model to use (default: gpt-4o-mini)\n  --auto-approve              Skip confirmation prompts for AI suggestions\n\nopenweight validate \u003cfile\u003e\n  -s, --schema \u003ctype\u003e         Schema: workout-log, workout-template, program, lifter-profile\n```\n\n### Supported formats\n\n| App        | Format | Notes                                    |\n|------------|--------|------------------------------------------|\n| **Strong** | CSV    | Requires `--weight-unit` (kg or lb)      |\n| **Hevy**   | CSV    | Auto-detects units from kg/lbs columns   |\n\n## Documentation\n\nFull documentation, schema reference, and interactive playground at **[openweight.dev](https://openweight.dev)**\n\n## SDKs\n\n| SDK        | Package                                                                                                      | Status    |\n|------------|--------------------------------------------------------------------------------------------------------------|-----------|\n| TypeScript | [@openweight/sdk](https://www.npmjs.com/package/@openweight/sdk)                                             | Published |\n| Kotlin     | [io.github.radupana:openweight-sdk](https://central.sonatype.com/artifact/io.github.radupana/openweight-sdk) | Published |\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup.\n\n### Releasing\n\nBoth SDKs share the same version. Releases are automated via GitHub Actions:\n\n1. Merge a PR with a [Conventional Commit](https://www.conventionalcommits.org/) title:\n    - `feat:` → minor bump\n    - `fix:` → patch bump\n    - `feat!:` or `BREAKING CHANGE:` → major bump\n2. The workflow creates a GitHub release and publishes to npm + Maven Central\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradupana%2Fopenweight","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fradupana%2Fopenweight","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradupana%2Fopenweight/lists"}