pcmarts/acl-recovery-tracker · v1.0.3
What an agent reads when it fetches this URL: the whole manifest, in order, with the offer on the last line as a 402 it can pay. Nothing here is a button — an agent does not click, it signs. The page a person reads is here.
Pack · 3 hooks · 29 source files · 2 docs · 2 CI files · 5 config files · 4 assets · 5 other files · 50 files · text 513 kB · binary 48.1 kB (9%) · TypeScript 91% · CSS 4% · PLpgSQL 3% · HTML 1% · other 1% · MIT, resale permitted
scan passed 2026-09-01 · scanner 2026.08.1 · 1 release · last release 15 days ago · 2% of files seen elsewhere
computed 2026-09-01 19:34 UTC · analyzer 0.1.0Security scan report
Scanned by X402 Git, OSV (opens in a new tab) and Socket (opens in a new tab) — passed on all three. Findings from all three are listed below.
- secrets
- none found
- X402 Git
- size limits
- within caps
- X402 Git
- known malware
- none in 545 packages
- OSV
- known vulnerabilities
- 1 moderate in 545 packages — see below
- OSV
- dependency behaviour
- 11 direct packages declare network access, filesystem access, environment variables and more · 1,116 more in transitive packages · 43 packages flagged for review
- Socket
- instruction smuggling
- none found
- X402 Git
- what it can do
- listed below
- X402 Git
What this can do
- Tools
- none
- Runs
- .github/workflows/audit.yml (push, pull_request, schedule, workflow_dispatch)
- .github/workflows/deploy.yml (push, workflow_dispatch)
- Talks to
- eslint.org
- fonts.googleapis.com
- fonts.gstatic.com
- github.com
- opencollective.com
- registry.npmjs.org
- tidelift.com
- user.github.io
- your-name.github.io
- your-project-ref.supabase.co
- Reads
- SUPABASE_ANON_KEY
- SUPABASE_URL
- VITE_BASE_PATH
- VITE_SUPABASE_ANON_KEY
- VITE_SUPABASE_URL
- At install
- nothing runs
- Links to
- nodejs.org
- supabase.com
- your-project-ref.supabase.co
Findings (130)
- HIGHjson-schema 0.4.0 (dev only) — json-schema 0.4.0 (transitive, dev only) — contains an obfuscated file
- MODERATE@humanfs/node 0.16.7 — @humanfs/node@0.16.7 (npm): humanfs: Recursive copy follows symlinked files and copies data from outside the source tree GHSA-p498-v437-472g
- flagged for reviewreact-dom 19.2.4 — react-dom 19.2.4 (direct) — flagged for review by Socket's classifier as a security risk
- flagged for review@rollup/plugin-terser 1.0.0 (dev only) — @rollup/plugin-terser 1.0.0 (transitive, dev only) — flagged for review by Socket's classifier as a security risk
- MODERATEesbuild 0.28.2 (dev only) — esbuild 0.28.2 (transitive, dev only) — install scripts run when installed
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATE@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — makes network requests at runtime
- MODERATEvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — makes network requests at runtime
- MODERATEvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — makes network requests at runtime
- MODERATEvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — makes network requests at runtime
- MODERATEvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — evaluates code at runtime
- MODERATE.github/workflows/audit.yml — A GitHub Actions workflow runs on push, pull_request, schedule, workflow_dispatch
- MODERATE.github/workflows/deploy.yml — A GitHub Actions workflow runs on push, workflow_dispatch
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — can attach a debugger
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — can attach a debugger
- LOWvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — can attach a debugger
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — can attach a debugger
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — deprecated by its author
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — loads modules by a computed name
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — loads modules by a computed name
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — loads modules by a computed name
- LOW.github/workflows/deploy.yml — Reads the environment variable SUPABASE_ANON_KEY
- LOW.github/workflows/deploy.yml — Reads the environment variable SUPABASE_URL
- LOW.github/workflows/deploy.yml — Reads the environment variable VITE_BASE_PATH
- LOW.github/workflows/deploy.yml — Reads the environment variable VITE_SUPABASE_ANON_KEY
- LOW.github/workflows/deploy.yml — Reads the environment variable VITE_SUPABASE_URL
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads environment variables
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads environment variables
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads environment variables
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads environment variables
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads environment variables
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads environment variables
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads environment variables
- LOWeslint-plugin-react-hooks 7.0.1 (dev only) — eslint-plugin-react-hooks 7.0.1 (direct, dev only) — reads environment variables
- LOWreact 19.2.4 — react 19.2.4 (direct) — reads environment variables
- LOWreact 19.2.4 — react 19.2.4 (direct) — reads environment variables
- LOWreact-dom 19.2.4 — react-dom 19.2.4 (direct) — reads environment variables
- LOWreact-dom 19.2.4 — react-dom 19.2.4 (direct) — reads environment variables
- LOWreact-dom 19.2.4 — react-dom 19.2.4 (direct) — reads environment variables
- LOWvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads environment variables
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — reads or writes files
- LOWvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — reads or writes files
- flagged for reviewvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — flagged for review by Socket's classifier as anomalous
- LOWvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — contains high-entropy strings
- LOWjiti 2.6.1 (dev only) — jiti 2.6.1 (transitive, dev only) — contains high-entropy strings
- LOWjiti 2.6.1 (dev only) — jiti 2.6.1 (transitive, dev only) — contains high-entropy strings
- LOWpackage-lock.json — Talks to eslint.org
- LOWindex.html — Talks to fonts.googleapis.com
- LOWindex.html — Talks to fonts.gstatic.com
- LOWpackage-lock.json — Talks to github.com
- LOWpackage-lock.json — Talks to opencollective.com
- LOWpackage-lock.json — Talks to registry.npmjs.org
- LOWpackage-lock.json — Talks to tidelift.com
- LOWvite.config.ts — Talks to user.github.io
- LOW.env.example — Talks to your-name.github.io
- LOW.env.example — Talks to your-project-ref.supabase.co
- LOW@supabase/supabase-js 2.98.0 — @supabase/supabase-js 2.98.0 (direct) — contains hard-coded URLs
- LOW@types/node 24.11.0 — @types/node 24.11.0 (direct) — contains hard-coded URLs
- LOW@vitejs/plugin-react 5.1.4 (dev only) — @vitejs/plugin-react 5.1.4 (direct, dev only) — contains hard-coded URLs
- LOWeslint 9.39.3 (dev only) — eslint 9.39.3 (direct, dev only) — contains hard-coded URLs
- LOWlucide-react 0.575.0 — lucide-react 0.575.0 (direct) — contains hard-coded URLs
- LOWreact 19.2.4 — react 19.2.4 (direct) — contains hard-coded URLs
- LOWreact-dom 19.2.4 — react-dom 19.2.4 (direct) — contains hard-coded URLs
- LOWtailwindcss 4.2.1 (dev only) — tailwindcss 4.2.1 (direct, dev only) — contains hard-coded URLs
- LOWvite 7.3.6 (dev only) — vite 7.3.6 (direct, dev only) — contains hard-coded URLs
- LOWvite-plugin-pwa 1.2.0 (dev only) — vite-plugin-pwa 1.2.0 (direct, dev only) — contains hard-coded URLs
- flagged for reviewgptAnomaly — 40 transitive packages, e.g. @babel/core@7.29.7, @babel/helper-module-imports@7.29.7, @babel/helper-module-transforms@7.29.7
- MODERATEusesEval — 23 transitive packages, e.g. @babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5, @babel/plugin-transform-async-generator-functions@7.29.0, @babel/plugin-transform-async-to-generator@7.28.6
- MODERATEnetworkAccess — 16 transitive packages, e.g. @supabase/auth-js@2.98.0, @supabase/functions-js@2.98.0, @supabase/postgrest-js@2.98.0
- MODERATEshellAccess — 9 transitive packages, e.g. @tailwindcss/oxide@4.2.1, commander@2.20.3, cross-spawn@7.0.6
- LOWurlStrings — 56 transitive packages, e.g. @babel/core@7.29.7, @babel/helper-create-class-features-plugin@7.28.6, @babel/helper-define-polyfill-provider@0.6.6
- LOWenvVars — 50 transitive packages, e.g. @babel/code-frame@7.29.7, @babel/core@7.29.7, @babel/helper-compilation-targets@7.29.7
- LOWfilesystemAccess — 40 transitive packages, e.g. @babel/core@7.29.7, @rollup/plugin-node-resolve@16.0.3, @tailwindcss/oxide@4.2.1
- LOWunmaintained — 40 transitive packages, e.g. acorn-jsx@5.3.2, at-least-node@1.0.0, buffer-from@1.1.2
- LOWdebugAccess — 12 transitive packages, e.g. @babel/core@7.29.7, @babel/helper-define-polyfill-provider@0.6.6, @humanwhocodes/module-importer@1.0.1
- LOWdynamicRequire — 10 transitive packages, e.g. @babel/helper-module-imports@7.29.7, @tailwindcss/oxide@4.2.1, browserslist@4.28.8
- LOWminifiedFile — 9 transitive packages, e.g. @isaacs/cliui@9.0.0, common-tags@1.8.2, esquery@1.7.0
- LOWnewAuthor — 4 transitive packages, e.g. async-function@1.0.0, convert-source-map@2.0.0, source-map@0.8.0-beta.0
- LOWtrivialPackage — 4 transitive packages, e.g. at-least-node@1.0.0, is-obj@1.0.1, is-regexp@1.0.0
- LOWdeprecated — 2 transitive packages, e.g. glob@11.1.0, source-map@0.8.0-beta.0
Description self_reported
Written by the creator. Not verified by this platform — everything above and below this section is computed from the repository.
tracks the recovery of your ACL when you've just had surgery
When to use it. when a user wants an app to track their ACL recovery
Readme
ACL Recovery Tracker
A progressive web app for tracking recovery after ACL reconstruction. It turns a surgery date into a week-by-week rehabilitation plan: the right exercises for your current phase, timers for ice and EMS sessions, weekly pain and range-of-motion check-ins, and a milestone timeline showing how far you've come.
Installs to the home screen on iOS and Android, works as a normal website everywhere else.
Version 1.0.3 · React 19 · TypeScript · Vite · Tailwind CSS 4 · Supabase
Not medical advice. This app follows a general ACL rehabilitation template. Recovery timelines vary by graft type, meniscus involvement and surgeon preference. Always follow the plan your surgeon and physiotherapist give you.
Features
| Phased plan | Five phases from Protection & Early Healing through Return to Activity, advancing automatically from your surgery date |
| Daily exercises | Grouped by strength, mobility, cardio, balance and recovery, with per-session tracking and a long-press shortcut to complete |
| Guided sessions | Step-by-step exercise player with set/rep counters, rest timers and audio cues |
| Timers | Presets for ice, EMS and collagen loading, with a screen wake lock so the display stays on |
| Weekly check-ins | Pain, swelling, extension and flexion, kept as a full history |
| Progress | Streaks, range-of-motion trend, milestone timeline and a browsable overview of the whole plan |
| EMS protocols | Per-phase electrode placement and stimulator settings |
| Offline-capable | Installable PWA with an auto-updating service worker |
Quick start
You'll need Node.js 20+ and a free Supabase account.
1. Install
git clone <your-repo-url>
cd acl-recovery-tracker
npm install
2. Create the database
- Create a new project at supabase.com/dashboard.
- Open SQL Editor → New query.
- Paste the contents of
supabase/schema.sqland click Run.
This creates four tables — exercise_logs, daily_logs, weekly_check_ins and user_settings — and enables row level security on each.
3. Configure
cp .env.example .env
Fill in the two values from Project Settings → Data API in your Supabase dashboard:
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key
4. Run
npm run dev
Open the URL it prints. On first launch you'll be asked for your name, surgery date and procedure — everything else is derived from those.
Deploying
The app is a static bundle, so any static host works. Set the two VITE_* environment variables in your host's dashboard before building.
GitHub Pages
A workflow is included at .github/workflows/deploy.yml.
- Settings → Pages → Source: GitHub Actions.
- Settings → Secrets and variables → Actions → Secrets: add
SUPABASE_URLandSUPABASE_ANON_KEY. - If you're deploying to a project site (
https://<user>.github.io/<repo>/), add a repository variable namedBASE_PATHset to/<repo>/.
Push to main and the workflow does the rest.
Netlify / Vercel / Cloudflare Pages
- Build command:
npm run build - Output directory:
dist - Environment variables:
VITE_SUPABASE_URL,VITE_SUPABASE_ANON_KEY
No BASE_PATH is needed — these serve from the root.
Security
Read this before sharing a deployment.
The app ships without authentication. It is built on the assumption that one deployment belongs to one person, which keeps setup to a single SQL paste and no login screen.
The consequence: the row level security policies in supabase/schema.sql grant full access to the anon role, so anyone who obtains your project URL and anon key can read and write your recovery data. Both values are embedded in the JavaScript bundle and are therefore visible to anyone who loads the page. For a personal deployment at an unlisted URL that is usually a reasonable trade-off — but it is a trade-off, and it is the wrong one if you plan to publish the link.
To make it genuinely multi-user:
- Enable an auth provider in Supabase → Authentication.
- Add
user_id uuid not null references auth.users default auth.uid()to each of the four tables. - Replace
using (true)in each policy withusing (auth.uid() = user_id). - Add a sign-in screen and gate the app on an active session.
Customising
Everything clinical lives in three plain data files — no database migration or component changes are needed to adapt the plan.
| File | Contents |
|---|---|
src/data/recoveryPlan.ts | Phase definitions (goals, cautions, week ranges) and every exercise: sets, reps, holds, frequency, instructions, progression notes |
src/data/milestones.ts | The milestone timeline and its target weeks |
src/data/emsProtocol.ts | Per-phase EMS settings and electrode placement |
Branding lives in src/config.ts (app name and tagline), vite.config.ts (PWA manifest) and src/index.css (the colour palette, defined as CSS custom properties on :root). Icons are in public/icons/.
If you are redistributing this as your own product, update the copyright holder in LICENSE to your own name or company.
Project structure
src/
├── components/ Reusable UI — cards, nav, timers, progress ring
├── config.ts App name, tagline, version
├── context/ Settings provider (profile + phase override)
├── data/ The recovery plan, milestones and EMS protocols
├── db/ Supabase client, types and queries
├── hooks/ usePhase, useDailyExercises, useTimer, useNotifications
├── pages/ Onboarding, Today, Exercise, Timers, Check-In, Progress, Settings
└── utils/ Shared date helpers
How the phase system works
usePhase() reads the surgery date from the settings context, converts it to a day count and then a week number, and looks up the matching phase in recoveryPlan.ts. useDailyExercises() filters exercises to that phase and merges them with today's logs. A user can override the phase manually from the Settings page when their physiotherapist moves them on early or holds them back.
Scripts
| Command | Description |
|---|---|
npm run dev | Start the dev server with hot reload |
npm run build | Type-check and build to dist/ |
npm run preview | Serve the production build locally |
npm run lint | Run ESLint |
npm run typecheck | Type-check without building |
Licence
MIT
Contents
| Size | Path |
|---|---|
| 621 B | .env.example · binary |
| 66 B | .gitattributes |
| 805 B | .github/workflows/audit.yml |
| 1.3 kB | .github/workflows/deploy.yml |
| 374 B | .gitignore |
| 1.1 kB | LICENSE |
| 7 kB | README.md |
| 1.6 kB | eslint.config.js |
| 1.6 kB | index.html |
| 296 kB | package-lock.json |
| 1.1 kB | package.json |
| 1.3 kB | public/404.html |
| 588 B | public/favicon.svg |
| 12.2 kB | public/icons/icon-192x192.png · binary |
| 35.3 kB | public/icons/icon-512x512.png · binary |
| 1.3 kB | src/App.tsx |
| 6.9 kB | src/components/ExerciseCard.tsx |
| 1.6 kB | src/components/Layout.tsx |
| 4 kB | src/components/MilestoneTimeline.tsx |
| 2.4 kB | src/components/NavBar.tsx |
| 2.5 kB | src/components/PhaseIndicator.tsx |
| 2.1 kB | src/components/ProgressRing.tsx |
| 5 kB | src/components/Timer.tsx |
| 370 B | src/config.ts |
| 3.8 kB | src/context/SettingsProvider.tsx |
| 1.3 kB | src/context/settingsContext.ts |
| 4.1 kB | src/data/emsProtocol.ts |
| 1.9 kB | src/data/milestones.ts |
| 36.2 kB | src/data/recoveryPlan.ts |
| 9.5 kB | src/db/database.ts |
| 6.5 kB | src/hooks/useDailyExercises.ts |
| 1.6 kB | src/hooks/usePhase.ts |
| 6.5 kB | src/hooks/useTimer.ts |
| 7.9 kB | src/index.css |
| 472 B | src/main.tsx |
| 6.3 kB | src/pages/CheckIn.tsx |
| 2.2 kB | src/pages/CheckInHelpers.tsx |
| 28.1 kB | src/pages/Exercise.tsx |
| 6.6 kB | src/pages/Onboarding.tsx |
| 12.6 kB | src/pages/Progress.tsx |
| 9.3 kB | src/pages/Settings.tsx |
| 4.8 kB | src/pages/Timers.tsx |
| 13.8 kB | src/pages/Today.tsx |
| 2.2 kB | src/utils/date.ts |
| 317 B | src/vite-env.d.ts |
| 5.1 kB | supabase/schema.sql |
| 732 B | tsconfig.app.json |
| 119 B | tsconfig.json |
| 653 B | tsconfig.node.json |
| 1.7 kB | vite.config.ts |
Dependencies
None found in the software bill of materials for this release.
computed 2026-09-01 19:34 UTC · analyzer 0.1.0Releases
| Version | Date | Scan | Changed | Notes |
|---|---|---|---|---|
| v1.0.3 | 2026-09-01 | pass | 3 files, 8 lines | **Version bump only.** No application code, dependency or database schema change since [v1.0.2](https://github.com/pcmarts/acl-recovery-tracker/releases/tag/v1.0.2) — the two trees are identical apart from the version string. If you are running v1.0.2, there is nothing to upgrade for. This tag exists to give the fixed scanner an unburned version number to verify against. A scan verdict is terminal, so v1.0.2 cannot be re-scanned and stays failed. ## Why v1.0.2 failed Its 8 HIGH findings (1 `react`, 7 `vite`) were artefacts of the scanner, not of this repository. Caret ranges in `package.json` could not be resolved to an exact version, so every dependency was queried twice — once **pinned** from `package-lock.json`, once **versionless** from `package.json`. Those dedupe to different keys, so both queries ran. A versionless OSV query is not a narrower question; it returns every advisory ever filed against the package at any version. One of the eight was filed against **Vite 2**, while this repo runs **7.3.6**. Measured separately over the v1.0.2 tree: | Half | Packages | Vulnerabilities | HIGH/CRITICAL | |---|---|---|---| | Pinned | 545 | 0 | **0** | | Versionless | 20 | 26 | **8** | All 8 blockers came from the phantom queries. No upgrade could clear them — which is why v1.0.2 failed on the same eight as v1.0.1, despite the commit in between genuinely fixing 15 real advisories. The scanner-side fix (`dedupePackages` now drops a versionless entry when the same `ecosystem|name` is pinned elsewhere) lives in the scanner's own codebase, not in this repository. ## Verified on this tree `npm audit` 0 vulnerabilities · `tsc -b` clean · `eslint` 0 errors · production build succeeds. ## Unchanged from v1.0.0 - The app ships **without authentication**. RLS is enabled but grants the `anon` role full access. See *Security* in the [README](README.md). - MIT permits buyers to redistribute and resell the source. - Not medical advice. |
| v1.0.2 | 2026-09-01 | fail | 4 files, 1,292 lines | Fixes the dependency advisories that failed the v1.0.1 release scan. **15 HIGH vulnerabilities, now 0.** No application code changed. ## Vulnerabilities fixed | Package | Affected | Issue | |---|---|---| | `vite` | `<=7.3.3` | Path traversal in optimized deps `.map` handling; `server.fs.deny` bypass via queries and Windows alternate paths; arbitrary file read via dev server WebSocket | | `react-router-dom` | `<=7.14.1` | Vulnerable via `react-router` | | `ws` | `8.0.0`–`8.20.1` | Uninitialized memory disclosure; memory exhaustion DoS | | `serialize-javascript` | `<=7.0.4` | RCE via `RegExp.flags`; CPU exhaustion DoS. Transitive through `workbox-build` → `@rollup/plugin-terser` | The `vite` and `react-router-dom` floors were raised in `package.json`, not just pinned in the lockfile — otherwise regenerating `package-lock.json` could land back on a vulnerable version. ## Also checked The scan could have failed on a secret or a size limit. Both were audited and were clean: - **Secrets** — no `.env` has ever been committed, `.env.example` contains only placeholders, and no credential-shaped strings exist in any tracked file. - **Size** — 660 KB tracked in total, the largest file being the 292 KB lockfile. ## Added `.github/workflows/audit.yml` runs `npm audit --audit-level=high` on every push and weekly, so new advisories surface immediately rather than at the next release scan. It is deliberately separate from the deploy workflow: a new advisory in a transitive dependency should report itself, not block a deploy of code that was already fine. ## Verified `npm ci` clean · `tsc -b` clean · `eslint` 0 errors · root and sub-path production builds both succeed. ## Unchanged from v1.0.0 - The app ships **without authentication**. RLS is enabled but grants the `anon` role full access. See *Security* in the [README](README.md). - MIT permits buyers to redistribute and resell the source. - Not medical advice. |
| v1.0.1 | 2026-09-01 | fail | 4 files, 14 lines | A metadata release. No application code, dependencies or database schema changed since [v1.0.0](https://github.com/pcmarts/acl-recovery-tracker/releases/tag/v1.0.0) — if you are already running it, there is nothing to upgrade for. ## Changed - **LICENSE** now names a real copyright holder. v1.0.0 shipped the placeholder `Copyright (c) 2026 ACL Recovery Tracker`, left over from stripping the fork of personal details. It now reads `Copyright (c) 2026 Paul Martin`. - **Version bumped to 1.0.1** in `package.json`, `package-lock.json` and the README. The version is injected into the bundle at build time and shown on the Settings page, so all four now agree. - **README** tells redistributors to substitute their own name in the licence, rather than implying the field was left unset. ## Still worth knowing Unchanged from v1.0.0, and both still apply: - The app ships **without authentication**. RLS is enabled but grants the `anon` role full access, and the anon key is visible in the JavaScript bundle — fine for one person at an unlisted URL, wrong if you publish the link. See *Security* in the [README](README.md). - MIT permits buyers to redistribute and resell the source. If that is not what you want from a paid product, swap the licence before distributing. - Not medical advice. |
| v1.0.0 | 2026-09-01 | fail | — | The first distributable release of ACL Recovery Tracker: a progressive web app that turns a surgery date into a week-by-week ACL rehabilitation plan. ## What it does - **Phased plan** — five phases from *Protection & Early Healing* through *Return to Activity*, advancing automatically from the user's surgery date, with a manual override for when a physio moves them on early. - **Daily exercises** — grouped by strength, mobility, cardio, balance and recovery, with per-session tracking and long-press to complete. - **Guided sessions** — step-by-step player with set/rep counters, rest timers and audio cues. - **Timers** — ice, EMS and collagen presets, with a screen wake lock. - **Weekly check-ins** — pain, swelling, extension and flexion, kept as history. - **Progress** — streaks, range-of-motion trend, milestone timeline and a browsable overview of the whole plan. - **EMS protocols** — per-phase electrode placement and stimulator settings. - **Installable PWA** — works offline, auto-updating service worker. ## Setting it up Requires Node.js 20+ and a free Supabase project. Run [`supabase/schema.sql`](supabase/schema.sql), copy `.env.example` to `.env`, fill in the two `VITE_SUPABASE_*` values, then `npm install && npm run dev`. Full instructions, deployment guides and customisation notes are in the [README](README.md). On first launch the app asks for a name, surgery date and procedure — nothing is hardcoded, and all three stay editable from Settings. ## Please read before sharing a deployment The app ships **without authentication**, on the assumption that one deployment belongs to one person. Row level security is enabled, but the policies grant the `anon` role full access, and the anon key is visible in the JavaScript bundle. Anyone who obtains your project URL and key can read and write the data. That is a reasonable trade-off for a personal deployment at an unlisted URL. It is the wrong one if you plan to publish the link. The *Security* section of the README sets out the four steps to make it genuinely multi-user. ## Notes - Licensed [MIT](LICENSE). Update the copyright holder before distributing. - `lucide-react` is pinned to `^0.575.0`; version `0.577.0` ships no type declarations and breaks `npm run build`. - Not medical advice. Recovery timelines vary by graft type, meniscus involvement and surgeon preference. |
Machine-readable at https://x402git.com/api/v/pcmarts/acl-recovery-tracker/releases. Entries cannot be deleted by the creator.
Order
GET v1.0.3 · $1 · new releases $0.20
The resource endpoint answers 402 with the price and the exact bytes to sign; the same request carrying PAYMENT-SIGNATURE returns a signed download URL. Access is granted only after settlement returns a transaction hash. A person can do the same thing with a browser wallet on the product page.
# the 402, with the price and the exact bytes to sign
curl -si https://x402git.com/api/r/pcmarts/acl-recovery-tracker
# what your wallet already owns, and what the next fetch would cost it
curl -s https://x402git.com/api/v/pcmarts/acl-recovery-tracker \
-H "X-Wallet-Signature: 0xYOURADDRESS.<nonce>.<signature>"The first request answers this — a real quote, made for this page load:
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"x402Version": 2,
"resource": {
"url": "https://x402git.com/api/r/pcmarts/acl-recovery-tracker",
"description": "pcmarts/acl-recovery-tracker v1.0.3 — release. tracks the recovery of your ACL when you've just had surgery Security scan passed; signed download, 5-minute URL.",
"mimeType": "application/zip",
"serviceName": "pcmarts/acl-recovery-tracker",
"tags": [
"pack",
"hooks",
"source",
"docs",
"ci"
]
},
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"amount": "1000000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xDbd32F7565FFdb901Ea48281777aD03d35bB4b60",
"maxTimeoutSeconds": 300,
"extra": {
"name": "USD Coin",
"version": "2"
},
"maxAmountRequired": "1000000",
"resource": "https://x402git.com/api/r/pcmarts/acl-recovery-tracker",
"description": "pcmarts/acl-recovery-tracker v1.0.3 — release. tracks the recovery of your ACL when you've just had surgery Security scan passed; signed download, 5-minute URL.",
"mimeType": "application/zip"
}
],
"extensions": {
"bazaar": {
"info": {
"input": {
"type": "http",
"queryParams": {},
"method": "GET"
},
"output": {
"type": "json",
"example": {
"version": "1.0.3",
"artifact_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"download_url": "https://storage.example/pcmarts/acl-recovery-tracker/1.0.3.zip?signed=…",
"expires_at": "2026-09-16T12:05:00.000Z",
"version_endpoint": "https://x402git.com/api/r/pcmarts/acl-recovery-tracker/v/1.0.3",
"manifest_url": "https://x402git.com/api/label/pcmarts/acl-recovery-tracker",
"all_versions": false
}
}
},
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"input": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "http"
},
"method": {
"type": "string",
"enum": [
"GET"
]
},
"queryParams": {
"type": "object",
"properties": {}
}
},
"required": [
"type",
"method"
],
"additionalProperties": false
},
"output": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"example": {
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "Semantic version of the release served."
},
"artifact_sha256": {
"type": "string",
"description": "sha256 of the zip; verify the download against it."
},
"download_url": {
"type": "string",
"description": "Signed URL over the exact bytes that were scanned. Valid five minutes."
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"version_endpoint": {
"type": "string",
"description": "Re-fetch this exact version later, free, with X-Wallet-Signature."
},
"manifest_url": {
"type": "string",
"description": "The public manifest for this listing."
},
"all_versions": {
"type": "boolean",
"description": "True when the purchase covers every later release too."
}
},
"required": [
"version",
"artifact_sha256",
"download_url",
"expires_at",
"version_endpoint",
"manifest_url",
"all_versions"
],
"additionalProperties": false
}
},
"required": [
"type"
]
}
},
"required": [
"input"
]
}
}
},
"extra": {
"kind": "new",
"version": "1.0.3",
"manifest_url": "https://x402git.com/api/label/pcmarts/acl-recovery-tracker",
"scan_badge_url": "https://x402git.com/api/label/pcmarts/acl-recovery-tracker#scan",
"update_price_micro": "200000",
"quote_id": "q_0c108c452bcd161364e8f2fc381e1cc1",
"valid_before": "2026-09-17T03:28:19.859Z",
"instructions": "This is an x402 paywall, not an error. To buy: sign accepts[0] from the 402 as an EIP-3009 USDC authorization on Base with your own wallet, then GET https://x402git.com/api/r/pcmarts/acl-recovery-tracker again with the payment in the PAYMENT-SIGNATURE header and extra.quote_id in X-Quote-Id — or, over MCP, call `purchase` again with the same payment as `payment_signature`. The full procedure is at https://x402git.com/.well-known/agent-skills/buy-a-repo/SKILL.md; the same tools are an MCP server at https://x402git.com/api/mcp. No wallet? A person can buy at https://x402git.com/pcmarts/acl-recovery-tracker, and the free manifest at https://x402git.com/api/label/pcmarts/acl-recovery-tracker shows what is inside before anyone pays.",
"listing_url": "https://x402git.com/pcmarts/acl-recovery-tracker",
"skill_url": "https://x402git.com/.well-known/agent-skills/buy-a-repo/SKILL.md",
"mcp_url": "https://x402git.com/api/mcp"
}
}- Resource
- https://x402git.com/api/r/pcmarts/acl-recovery-tracker
- Manifest
- https://x402git.com/api/label/pcmarts/acl-recovery-tracker
- Version
- https://x402git.com/api/v/pcmarts/acl-recovery-tracker
- Artifact sha256
- 73afc3c52d0fae60616ca57755b823e2435ee9916155fff7bd357277f7de0700
Later releases cost $0.20, and never more than the update price in force when you bought. One charge per update, whatever the release cadence.
Sold by pcmarts. Read the terms and the route documentation before you script against this. Base URL https://x402git.com.