diff --git a/.husky/commit-msg b/.husky/commit-msg index 4b8c242d..cc1ce805 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,9 +1,7 @@ -#!/usr/bin/env bash # # Husky Commit Message Hook # Validates commit message format using commitlint # -. "$(dirname -- "$0")/_/husky.sh" # Run commitlint but don't fail the commit (|| true) # This provides helpful feedback without blocking commits diff --git a/.husky/pre-commit b/.husky/pre-commit index b31dbcc0..f122047f 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,9 +1,7 @@ -#!/usr/bin/env bash # # Husky Pre-commit Hook # Runs lint-fix and Build Architecture Guard on staged files # -. "$(dirname -- "$0")/_/husky.sh" echo "🔍 Running pre-commit hooks..." diff --git a/.husky/pre-push b/.husky/pre-push index 2d79fde4..67780a48 100755 --- a/.husky/pre-push +++ b/.husky/pre-push @@ -1,9 +1,7 @@ -#!/usr/bin/env bash # # Husky Pre-push Hook # Runs Build Architecture Guard to check commits being pushed # -. "$(dirname -- "$0")/_/husky.sh" echo "🔍 Running Build Architecture Guard (pre-push)..." diff --git a/CHANGELOG.md b/CHANGELOG.md index 77e8a833..1fb1bbff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [?] - 2026 ### Added -- Full flow for setting up SMS notifications -- SMS notifications talk to the notify-api: phone registration and code +- Full flow for setting up SMS notifications: phone registration and code verification, delegated alertSearch JWT batches with a send hour, and revocation to stop the texts - Push-channel client for the notify-api's alert authorization diff --git a/README.md b/README.md index 2af6c457..0f4688f9 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,15 @@ Assumes Xcode and Xcode Command Line Tools are installed. See [BUILDING.md](BUILDING.md) for comprehensive build instructions for all platforms (Web, Electron, iOS, Android, Docker). +## Tests + +``` +npm run test:web + +# ... or do every check: +npm run test:all +``` + ## 🛡️ Build Architecture Guard This project uses **Husky Git hooks** to protect the build system diff --git a/package-lock.json b/package-lock.json index bf3ef7ea..3e190ce7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -153,7 +153,8 @@ "ts-jest": "^29.4.0", "tsx": "^4.20.4", "typescript": "~5.2.2", - "vite": "^5.2.0" + "vite": "^5.2.0", + "vue-tsc": "^2.1.10" } }, "node_modules/@adraffy/ens-normalize": { @@ -11605,6 +11606,35 @@ "vue": "^3.2.25" } }, + "node_modules/@volar/language-core": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz", + "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.28" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz", + "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz", + "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, "node_modules/@vue-leaflet/vue-leaflet": { "version": "0.10.1", "license": "MIT", @@ -11663,6 +11693,17 @@ "@vue/shared": "3.5.13" } }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, "node_modules/@vue/devtools-api": { "version": "6.6.4", "license": "MIT" @@ -11890,6 +11931,31 @@ "node": ">=4.0" } }, + "node_modules/@vue/language-core": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.1.10.tgz", + "integrity": "sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "~2.4.8", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^0.2.0", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@vue/reactivity": { "version": "3.5.13", "license": "MIT", @@ -12155,6 +12221,13 @@ "ajv": "^6.9.1" } }, + "node_modules/alien-signals": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-0.2.2.tgz", + "integrity": "sha512-cZIRkbERILsBOXTQmMrxc9hgpxglstn69zm+F1ARf4aPAzdAFYd6sBq87ErO0Fj3DV94tglcyHG5kQz9nDC/8A==", + "dev": true, + "license": "MIT" + }, "node_modules/anser": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", @@ -15004,6 +15077,13 @@ "version": "1.11.13", "license": "MIT" }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, "node_modules/debug": { "version": "4.3.4", "license": "MIT", @@ -23436,6 +23516,13 @@ "license": "Apache-2.0", "optional": true }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, "node_modules/multibase": { "version": "4.0.6", "license": "MIT", @@ -30292,6 +30379,13 @@ "optional": true, "peer": true }, + "node_modules/vscode-uri": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.2.0.tgz", + "integrity": "sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==", + "dev": true, + "license": "MIT" + }, "node_modules/vue": { "version": "3.5.13", "license": "MIT", @@ -30433,6 +30527,24 @@ "vue": "^3.2.0" } }, + "node_modules/vue-tsc": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.1.10.tgz", + "integrity": "sha512-RBNSfaaRHcN5uqVqJSZh++Gy/YUzryuv9u1aFWhsammDJXNtUiJMNoJ747lZcQ68wUQFx6E73y4FY3D8E7FGMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "~2.4.8", + "@vue/language-core": "2.1.10", + "semver": "^7.5.4" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, "node_modules/walker": { "version": "1.0.8", "devOptional": true, diff --git a/package.json b/package.json index dddf9695..a8addc95 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "lint-fix": "eslint --ext .js,.ts,.vue --ignore-path .gitignore --fix src", "type-safety-check": "./scripts/type-safety-check.sh", "type-check": "tsc --noEmit", + "type-check:vue": "vue-tsc --noEmit", "prebuild": "eslint --ext .js,.ts,.vue --ignore-path .gitignore src && node sw_combine.js && node scripts/copy-wasm.js", "test:prerequisites": "node scripts/check-prerequisites.js", "check:dependencies": "./scripts/check-dependencies.sh", @@ -282,6 +283,7 @@ "ts-jest": "^29.4.0", "tsx": "^4.20.4", "typescript": "~5.2.2", - "vite": "^5.2.0" + "vite": "^5.2.0", + "vue-tsc": "^2.1.10" } } diff --git a/src/components/ChoiceButtonDialog.vue b/src/components/ChoiceButtonDialog.vue index 21624aae..3dae5622 100644 --- a/src/components/ChoiceButtonDialog.vue +++ b/src/components/ChoiceButtonDialog.vue @@ -25,6 +25,7 @@
{{ text }}
-+ Get told about new relevant activity for you. Choose a delivery + channel below -- you can turn on either one, or both. +
+- This is a reliable message, but it doesn't contain any details about + This is your own message activated in the app, but it doesn't contain any details about activity that might be especially interesting to you. + Note that the timing is not precise: the device may deliver it a bit later than scheduled.
- The New Activity Notification will be sent to you when there is new, relevant activity - for you. + The New Activity Notification will be activated in your app when there is new, relevant + activity for you. It will only trigger if something involves you or a project of interest; it will not bug you for other, general activity.
+
- This type is not as reliable as a Reminder Notification because mobile devices often
- suppress such notifications to save battery. (If you want to quickly check for relevant
- activity daily, use the Reminder Notification and open the app and look for a large green
- button that points out new activity that is personal to you. We are working on other
- ways to notify you more reliably.
-
Notes and caveats for text messages: