Skip to content

Commit 88f1aef

Browse files
chore: migrate from Biome to ESLint/Prettier for code formatting (#29)
1 parent 68619f0 commit 88f1aef

32 files changed

+1641
-836
lines changed

.github/workflows/test.yml

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
name: Test
22

33
on:
4-
push:
5-
branches: [ main ]
6-
pull_request:
4+
push:
5+
branches: [main]
6+
pull_request:
77

88
jobs:
9-
build:
10-
runs-on: ubuntu-latest
11-
steps:
12-
- uses: actions/checkout@v4
13-
- uses: actions/setup-node@v4
14-
with:
15-
node-version: 20
16-
cache: 'yarn'
17-
- name: Install dependencies
18-
run: yarn install --frozen-lockfile
19-
- name: Generate SvelteKit types
20-
run: yarn prepare
21-
- name: Run tests with coverage
22-
run: yarn test:coverage
23-
- name: Upload coverage report
24-
uses: actions/upload-artifact@v4
25-
with:
26-
name: coverage-report
27-
path: coverage
28-
if-no-files-found: warn
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-node@v4
14+
with:
15+
node-version: 20
16+
cache: 'yarn'
17+
- name: Install dependencies
18+
run: yarn install --frozen-lockfile
19+
- name: Generate SvelteKit types
20+
run: yarn prepare
21+
- name: Run tests with coverage
22+
run: yarn test:coverage
23+
- name: Upload coverage report
24+
uses: actions/upload-artifact@v4
25+
with:
26+
name: coverage-report
27+
path: coverage
28+
if-no-files-found: warn

.prettierrc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"useTabs": false,
3+
"tabWidth": 4,
4+
"semi": false,
5+
"singleQuote": true,
6+
"trailingComma": "es5",
7+
"printWidth": 100,
8+
"plugins": ["prettier-plugin-svelte"],
9+
"overrides": [
10+
{
11+
"files": "*.svelte",
12+
"options": {
13+
"parser": "svelte"
14+
}
15+
}
16+
]
17+
}

README.md

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ WellSaid helps you communicate with more empathy and clarity by offering convers
99
- **Smart Reply Suggestions**: Get short, medium, and long AI-generated reply options (via OpenAI or a local Khoj server) based on conversation context
1010
- **Conversation History Context**: Considers recent message history (configurable via `HISTORY_LOOKBACK_HOURS`) to provide more contextually relevant suggestions
1111
- **Tone Selection**: Choose from four different tones for your replies:
12-
- Gentle
13-
- Funny
14-
- Reassuring
15-
- Concise
12+
- Gentle
13+
- Funny
14+
- Reassuring
15+
- Concise
1616
- **Context Addition**: Add additional context to help generate more relevant replies
1717
- **Message Database Integration**: Connects to your macOS Messages app database
1818
- **Real-time Updates**: Dynamic UI with loading indicators and real-time feedback
@@ -29,21 +29,24 @@ WellSaid helps you communicate with more empathy and clarity by offering convers
2929
To use WellSaid with OpenAI's models, you'll need an API key. Here's how to get one:
3030

3131
1. **Sign up for an account**
32-
- Go to [OpenAI's website](https://platform.openai.com/signup)
33-
- Create an account or sign in if you already have one
32+
33+
- Go to [OpenAI's website](https://platform.openai.com/signup)
34+
- Create an account or sign in if you already have one
3435

3536
2. **Access the API key section**
36-
- After logging in, click on your profile icon in the top-right corner
37-
- Select "View API keys" from the dropdown menu
37+
38+
- After logging in, click on your profile icon in the top-right corner
39+
- Select "View API keys" from the dropdown menu
3840

3941
3. **Create a new secret key**
40-
- Click on "Create new secret key"
41-
- Give your key a name (e.g., "WellSaid Development")
42-
- Click "Create secret key"
43-
- **Important**: Copy the key immediately - you won't be able to see it again!
42+
43+
- Click on "Create new secret key"
44+
- Give your key a name (e.g., "WellSaid Development")
45+
- Click "Create secret key"
46+
- **Important**: Copy the key immediately - you won't be able to see it again!
4447

4548
4. **Add the key to your environment**
46-
- Paste the key as the value for `OPENAI_API_KEY` in your `.env` file
49+
- Paste the key as the value for `OPENAI_API_KEY` in your `.env` file
4750

4851
**Note**: OpenAI API usage is not free. You'll be charged based on the number of tokens processed. Check [OpenAI's pricing page](https://openai.com/pricing) for current rates.
4952

@@ -117,14 +120,15 @@ HISTORY_LOOKBACK_HOURS=6
117120
CUSTOM_CONTEXT=your-custom-context
118121
```
119122

120-
**Important Note on `JWT_SECRET`**:
123+
**Important Note on `JWT_SECRET`**:
121124
The `JWT_SECRET` is critical for securing your application's authentication. It should be a long, random, and unpredictable string. **Do not use a weak or easily guessable secret.**
122125

123126
You can generate a strong secret using OpenSSL with the following command in your terminal:
124127

125128
```bash
126129
openssl rand -base64 64
127130
```
131+
128132
Copy the output of this command and use it as the value for `JWT_SECRET` in your `.env` file. Ensure it's on a single line.
129133

130134
4. Start the development server
@@ -213,19 +217,21 @@ mkcert -install
213217
```bash
214218
mkcert <your-tailscale-hostname>.<tailscale-subdomain>.ts.net localhost
215219
```
220+
216221
This will create a cert/key pair like `rootCA.pem` and `rootCA-key.pem`.
217222

218223
3. **Trust the cert on your iPhone**
219224

220225
- Convert the root CA to iOS-compatible format:
226+
221227
```bash
222228
openssl x509 -inform PEM -in "$(mkcert -CAROOT)/rootCA.pem" -outform DER -out mkcert-rootCA.cer
223229
```
224230

225231
- AirDrop or email the `mkcert-rootCA.cer` file to your iPhone
226232
- Open it, then go to:
227-
- **Settings → General → VPN & Device Management → Install Profile**
228-
- **Settings → General → About → Certificate Trust Settings → Enable full trust** for mkcert root
233+
- **Settings → General → VPN & Device Management → Install Profile**
234+
- **Settings → General → About → Certificate Trust Settings → Enable full trust** for mkcert root
229235

230236
Now when you visit your app over HTTPS (via Safari), iOS will trust the cert, and your manifest and icon will load properly — giving your app a real custom icon when added to the Home Screen.
231237

biome.json

Lines changed: 0 additions & 46 deletions
This file was deleted.

eslint.config.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import js from '@eslint/js'
2+
import ts from '@typescript-eslint/eslint-plugin'
3+
import tsParser from '@typescript-eslint/parser'
4+
import svelte from 'eslint-plugin-svelte'
5+
import svelteParser from 'svelte-eslint-parser'
6+
import prettier from 'eslint-config-prettier'
7+
import globals from 'globals'
8+
9+
export default [
10+
js.configs.recommended,
11+
{
12+
files: ['**/*.{js,ts,mjs}'],
13+
languageOptions: {
14+
parser: tsParser,
15+
parserOptions: {
16+
ecmaVersion: 2022,
17+
sourceType: 'module',
18+
},
19+
globals: {
20+
...globals.node,
21+
...globals.browser,
22+
},
23+
},
24+
plugins: {
25+
'@typescript-eslint': ts,
26+
},
27+
rules: {
28+
...ts.configs.recommended.rules,
29+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
30+
'@typescript-eslint/no-explicit-any': 'warn',
31+
},
32+
},
33+
{
34+
files: ['**/*.svelte'],
35+
languageOptions: {
36+
parser: svelteParser,
37+
parserOptions: {
38+
parser: tsParser,
39+
extraFileExtensions: ['.svelte'],
40+
},
41+
globals: {
42+
...globals.browser,
43+
},
44+
},
45+
plugins: {
46+
svelte,
47+
},
48+
rules: {
49+
...svelte.configs.recommended.rules,
50+
'svelte/valid-compile': 'error',
51+
'svelte/no-at-debug-tags': 'warn',
52+
},
53+
},
54+
{
55+
files: ['tests/**/*.{js,ts}', '**/*.test.{js,ts}', '**/*.spec.{js,ts}'],
56+
languageOptions: {
57+
globals: {
58+
...globals.node,
59+
...globals.browser,
60+
vi: 'readonly',
61+
describe: 'readonly',
62+
it: 'readonly',
63+
test: 'readonly',
64+
expect: 'readonly',
65+
beforeAll: 'readonly',
66+
afterAll: 'readonly',
67+
beforeEach: 'readonly',
68+
afterEach: 'readonly',
69+
},
70+
},
71+
rules: {
72+
'@typescript-eslint/no-unused-vars': 'off',
73+
},
74+
},
75+
{
76+
files: ['vite.config.ts', 'vitest.config.ts', 'svelte.config.js'],
77+
languageOptions: {
78+
globals: {
79+
...globals.node,
80+
__dirname: 'readonly',
81+
},
82+
},
83+
},
84+
{
85+
ignores: [
86+
'.svelte-kit/**',
87+
'build/**',
88+
'dist/**',
89+
'node_modules/**',
90+
'coverage/**',
91+
'**/*.d.ts',
92+
],
93+
},
94+
prettier,
95+
]

package.json

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,22 @@
44
"version": "0.0.1",
55
"type": "module",
66
"scripts": {
7-
"biome:lint": "npx @biomejs/biome lint .",
8-
"biome:format": "npx @biomejs/biome format . --write",
97
"dev": "vite dev",
108
"build": "vite build",
119
"preview": "vite preview",
1210
"prepare": "svelte-kit sync || echo ''",
1311
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
1412
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
15-
"format": "yarn biome:format",
16-
"lint": "yarn biome:lint",
13+
"format": "prettier --write .",
14+
"format:check": "prettier --check .",
15+
"lint": "eslint .",
16+
"lint:fix": "eslint --fix .",
1717
"pretest": "svelte-kit sync",
1818
"test": "vitest run",
1919
"test:watch": "vitest",
2020
"test:coverage": "vitest run --coverage"
2121
},
2222
"devDependencies": {
23-
"@biomejs/biome": "^1.9.4",
2423
"@sveltejs/adapter-auto": "^6.0.0",
2524
"@sveltejs/kit": "^2.16.0",
2625
"@sveltejs/vite-plugin-svelte": "^5.0.0",
@@ -29,9 +28,16 @@
2928
"@types/basic-auth": "^1.1.8",
3029
"@types/jsonwebtoken": "^9.0.9",
3130
"@types/node": "^22.15.21",
31+
"@typescript-eslint/eslint-plugin": "^8.34.0",
32+
"@typescript-eslint/parser": "^8.34.0",
3233
"@vitest/coverage-v8": "^3.1.4",
34+
"eslint": "^9.28.0",
35+
"eslint-config-prettier": "^10.1.5",
36+
"eslint-plugin-svelte": "^3.9.1",
3337
"globals": "^16.0.0",
3438
"jsdom": "^26.1.0",
39+
"prettier": "^3.5.3",
40+
"prettier-plugin-svelte": "^3.4.0",
3541
"svelte": "^5.0.0",
3642
"svelte-check": "^4.0.0",
3743
"typescript": "^5.0.0",

src/app.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import url("./variables.css");
1+
@import url('./variables.css');
22

33
*,
44
*::before,
@@ -12,7 +12,7 @@ body {
1212
padding: 1rem;
1313
min-height: 100vh;
1414
background: #bee3db
15-
url("data:image/png;base64,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");
15+
url('data:image/png;base64,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');
1616
color: #555b6e;
1717
display: flex;
1818
flex-direction: column;
@@ -42,7 +42,7 @@ select {
4242
border: 1px solid var(--light);
4343
background-color: var(--white);
4444
appearance: none;
45-
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23555B6E%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
45+
background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23555B6E%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
4646
background-repeat: no-repeat;
4747
background-position: right 0.7rem top 50%;
4848
background-size: 0.65rem auto;

0 commit comments

Comments
 (0)