Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8e96f4e
Update Functions
epodol Jul 17, 2023
9e5e8d6
Update to Node 18
epodol Jul 17, 2023
70dbdf3
Transition to Vite
epodol Jul 19, 2023
b13a17e
Add revival roadmap
epodol Jul 6, 2026
15746f5
Modernize CI/CD workflows: actions v4, Node 20, drop archived actions
epodol Jul 6, 2026
a635722
Merge remote-tracking branch 'origin/release-0.2.0' into revival
epodol Jul 6, 2026
363ea91
Node 24 everywhere; modernize Cloud Functions deps
epodol Jul 6, 2026
b0acde4
Update root deps: in-range bumps, TS 5.9, firebase-tools 15, drop dotenv
epodol Jul 6, 2026
cfbcf2b
Vite stack majors: vite 8, vitest 4, plugin-react 6, PWA plugin 1.x
epodol Jul 6, 2026
eee6557
react-router-dom 7; migrate zoom-pan-pinch from dead @kokarn fork to …
epodol Jul 6, 2026
def20a5
Final dep bumps: testing-library 16/jest-dom 6, @types/jest 30, zoom-…
epodol Jul 6, 2026
04e7235
Roadmap: add status section and wave-sequenced next steps
epodol Jul 6, 2026
ca63b4e
CI: install JDK 21 for Tests job (firebase-tools 15 requires Java 21+)
epodol Jul 6, 2026
85602c0
Move ROADMAP.md to changelog/2026-07-04-revival-roadmap.md (PR review…
epodol Jul 6, 2026
d0e84be
Fix Firestore rules privilege escalation; add rules unit tests (#188)
epodol Jul 6, 2026
fa80084
.env hygiene: untrack .env, commit .env.example, gitignore env files …
epodol Jul 6, 2026
e716c2d
Replace dead react-hotkeys with react-hotkeys-hook 5 (#192)
epodol Jul 6, 2026
4cabca9
Service worker: keep PWA via vite-plugin-pwa, delete CRA-era SW (#194)
epodol Jul 6, 2026
7e6e168
Fix Home page logo: drop CRA-era process.env.PUBLIC_URL (undefined un…
epodol Jul 6, 2026
e5a104d
Prettier: collapse Logo props after PUBLIC_URL fix
epodol Jul 6, 2026
3d77488
Roadmap: record Wave 1 completion, cherry-pick findings, Wave 2 hando…
epodol Jul 6, 2026
620f362
Write model: UUID node IDs + Firestore transactions (#195)
epodol Jul 6, 2026
36d439d
Replace dead OpenAI completions with Groq chat completions (#190)
epodol Jul 6, 2026
3712cd5
Roadmap: record Wave 2 completion (#195 write model, #190 Groq swap)
epodol Jul 6, 2026
d0597dd
Replace reactfire with custom firebase hooks; firebase 12 (#191)
epodol Jul 7, 2026
1630982
MUI 5 -> 9 and React 18 -> 19 (#193)
epodol Jul 7, 2026
6a0751d
Roadmap: record Wave 3 completion (#191 reactfire removal, #193 MUI 9…
epodol Jul 7, 2026
c0ceaf7
Add PNG, SVG, and Markdown export of mind maps (#197)
epodol Jul 7, 2026
3e171af
Session-local undo for the mind-map editor (#198)
epodol Jul 7, 2026
4791c69
Privacy policy page (DRAFT) and site footer (#196)
epodol Jul 7, 2026
9276149
Roadmap: record Wave 4 completion (#197 export, #198 undo, #196 priva…
epodol Jul 7, 2026
e5b0113
Privacy policy: ads wording, in-app account deletion, drop home-page …
epodol Jul 7, 2026
224a0d1
Home page refresh: expanded landing sections + SEO
epodol Jul 7, 2026
d0d131b
Commit App Check reCAPTCHA v3 site key
epodol Jul 7, 2026
5703379
Remove .claude dir from prettier
epodol Jul 7, 2026
1ff7df2
Update homepage
epodol Jul 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .claude/skills/verify/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
name: verify
description: Build, launch, and drive bubblemap locally to verify UI changes end-to-end with Playwright screenshots.
---

# Verifying bubblemap changes in the running app

## Environment gotchas (do these first)

- The default shell is Node 16: `source ~/.nvm/nvm.sh && nvm use 24` before
any npm/npx/firebase command.
- Emulators need JDK 21: `export JAVA_HOME=/opt/homebrew/opt/openjdk@21;
export PATH="$JAVA_HOME/bin:$PATH"`.
- Never start the hosting emulator locally β€” macOS ControlCenter squats
port 5000. Always pass `--only`.

## Launch (two background processes)

```bash
npx firebase-tools emulators:start --only firestore,auth -P testing
BROWSER=none npx vite --port 5173 --strictPort
```

Add `functions` to `--only` (and build ./functions first) if the flow under
test calls the suggestion backend; otherwise the canvas logs
`internal` / connection-refused errors on 5001 that are environment noise,
not bugs.

Ready when `curl localhost:9099` returns 200 and `curl localhost:5173`
returns the HTML shell. Dev mode (`MODE !== 'production'`) auto-connects to
the emulators and skips App Check.

## Drive

Playwright works well (install once: `npx playwright install chromium`;
`npm i playwright` in a scratch dir, not the repo). Useful flows:

- Signed-out home: fresh context β†’ `/` β†’ h1 "Bubble Map", primary CTA
"Create Your First MindMap".
- Full CTA flow: click the CTA β†’ anonymous sign-in β†’ new map β†’
`waitForURL('**/mindmaps/**')` β†’ canvas shows root bubble + unclaimed-
account banner.
- Signed-in home state: revisit `/` in the same context β†’ CTA becomes
"Browse Your Mindmaps".
- Dark mode: new context with `colorScheme: 'dark'` β†’ body background
should be `rgb(18, 18, 18)`.
- Mobile: 375px viewport; assert
`document.documentElement.scrollWidth <= clientWidth`.
- Capture `pageerror` + console errors; home page should produce zero.

Screenshots to the session scratchpad, full-page for marketing routes.
18 changes: 0 additions & 18 deletions .env

This file was deleted.

29 changes: 29 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copy this file to `.env` before running or building the app:
# cp .env.example .env
#
# These are Firebase Web SDK config values: public, client-visible
# identifiers (they ship in the JS bundle), NOT secrets. The values below
# are the official bubblemap projects' config; replace them with your own
# Firebase project's config if you are working from a fork. The real
# security boundary is Firestore rules, App Check, and API-key HTTP
# referrer restrictions β€” never put actual secrets in VITE_* variables.

# Production project (bubblemap-app)
VITE_FIREBASE_API_KEY=AIzaSyAcH2oqXkfT2gJjbgmQeU62GmHy78PXyww
VITE_FIREBASE_AUTH_DOMAIN=bubblemap-app.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=bubblemap-app
VITE_FIREBASE_STORAGE_BUCKET=bubblemap-app.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=961385019430
VITE_FIREBASE_APP_ID=1:961385019430:web:d81b367e47eaecfc430ee7
VITE_FIREBASE_MEASUREMENT_ID=G-EYXHSKR3ZV

# Development/testing project (mind-map-testing) β€” used when MODE !== 'production'
VITE_FIREBASE_API_KEY_DEV=AIzaSyD-oEhhMx9GRPYa1Dn6qhFR_yBV18KOY8Q
VITE_FIREBASE_AUTH_DOMAIN_DEV=mind-map-testing.firebaseapp.com
VITE_FIREBASE_PROJECT_ID_DEV=mind-map-testing
VITE_FIREBASE_STORAGE_BUCKET_DEV=mind-map-testing.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID_DEV=427950169016
VITE_FIREBASE_APP_ID_DEV=1:427950169016:web:ca279979776510972d0d4d
VITE_FIREBASE_MEASUREMENT_ID_DEV=G-GZZRF9XDMM

VITE_RECAPTCHA_PUBLIC_KEY=6LfGWUgtAAAAAHD94Wv7luFfyoAq45ebU6FnyZzz
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ module.exports = {
'react/require-default-props': 'off',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
},
settings: {
jest: {
version: 'latest',
},
// ESM-only packages resolved via package.json "exports", which
// eslint-plugin-import's node resolver cannot follow
'import/core-modules': ['vite', '@vitejs/plugin-react'],
},
};
4 changes: 2 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

1. Ensure you have the following installed:

- Node.JS v16
- Node Package Manager v8
- Node.JS v24
- Node Package Manager v11
- Firebase CLI

1. Clone the repo
Expand Down
72 changes: 29 additions & 43 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,20 @@ jobs:
name: Upload Build and Deploy to Firebase
if: github.repository_owner == 'SpiritSeal'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
node-version: '24'
cache: 'npm'
cache-dependency-path: |
package-lock.json
functions/package-lock.json

- name: Install ./ Dependencies
run: npm ci --prefer-offline --no-audit
Expand All @@ -39,6 +33,9 @@ jobs:
- name: TSC
run: npm run tsc

- name: Create .env from .env.example
run: cp .env.example .env

- name: Build React
run: npm run build

Expand All @@ -47,37 +44,26 @@ jobs:
zip -r build.zip build
tar -czf build.tar.gz build

- name: Upload .zip Build Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./build.zip
asset_name: build.zip
asset_content_type: application/zip

- name: Upload .tar.gz Build Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Build Assets to Release
uses: softprops/action-gh-release@v2
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./build.tar.gz
asset_name: build.tar.gz
asset_content_type: application/gzip
files: |
build.zip
build.tar.gz

- name: Deploy to Firebase
uses: w9jds/firebase-action@master
with:
args: deploy -P testing --force
- name: Deploy to Firebase (testing)
run: |
echo "$GCP_SA_KEY" > "$RUNNER_TEMP/gcp_sa_key.json"
npx firebase-tools deploy -P testing --force
env:
GCP_SA_KEY: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_MIND_MAP_TESTING }}'
GCP_SA_KEY: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_MIND_MAP_TESTING }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ runner.temp }}/gcp_sa_key.json

- name: Deploy to Firebase
- name: Deploy to Firebase (production)
if: '!github.event.release.prerelease'
uses: w9jds/firebase-action@master
with:
args: deploy -P app --force
run: |
echo "$GCP_SA_KEY" > "$RUNNER_TEMP/gcp_sa_key.json"
npx firebase-tools deploy -P app --force
env:
GCP_SA_KEY: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_BUBBLEMAP_APP }}'
GCP_SA_KEY: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_BUBBLEMAP_APP }}
GOOGLE_APPLICATION_CREDENTIALS: ${{ runner.temp }}/gcp_sa_key.json
72 changes: 27 additions & 45 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
node-version: '24'
cache: 'npm'
cache-dependency-path: |
package-lock.json
functions/package-lock.json

- name: Install ./ Dependencies
run: npm ci --prefer-offline --no-audit
Expand All @@ -48,24 +40,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
node-version: '24'
cache: 'npm'
cache-dependency-path: |
package-lock.json
functions/package-lock.json

- name: Install ./ Dependencies
run: npm ci --prefer-offline --no-audit
Expand All @@ -85,27 +69,25 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
node-version: '24'
cache: 'npm'
cache-dependency-path: |
package-lock.json
functions/package-lock.json

- name: Setup Java (required by Firebase emulators)
uses: actions/setup-java@v4
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
distribution: 'temurin'
java-version: '21'

- name: Cache Firebase Emulators
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: ~/.cache/firebase/emulators
key: ${{ runner.os }}-firebase-emulators
Expand Down
27 changes: 10 additions & 17 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '16'

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
node-version: '24'
cache: 'npm'
cache-dependency-path: |
package-lock.json
functions/package-lock.json

- name: Install ./ Dependencies
run: npm ci --prefer-offline --no-audit
Expand All @@ -38,6 +30,9 @@ jobs:
- name: TSC
run: npm run tsc

- name: Create .env from .env.example
run: cp .env.example .env

- name: Build React
run: npm run build

Expand All @@ -48,5 +43,3 @@ jobs:
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_MIND_MAP_TESTING }}
projectId: mind-map-testing
target: default
env:
FIREBASE_CLI_PREVIEWS: hostingchannels
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,7 @@ tsconfig.tsbuildinfo

*.secret

.runtimeconfig.json
# Local environment files (copy from .env.example)
.env
.env.local
.env.*.local
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24
Loading
Loading