Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .changelog/v0.7.x.md → .changelog/v0.7.12.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Release v0.7.x - Migration Map, AI Discovery Improvements
# Release v0.7.12 - Migration Map, AI Discovery Improvements

Released: Unreleased

Expand All @@ -23,7 +23,7 @@ This release improves the AI Discovery feature with dismiss functionality, debug
- GET `/api/ai-discovery/debug/runs/:runId` - detailed run info including prompt preview and output
- Error details capture (last 10 lines of stderr/stdout) stored on failed runs

### Migration Map Visualization (v0.7.x)
### Migration Map Visualization (v0.7.12)
- New 6th tree view mode: "Migration Map" plots ancestors on an interactive world map
- Leaflet.js map with OpenStreetMap/CartoDB dark tiles
- Lineage-colored markers (paternal=blue, maternal=red) with generation depth variation
Expand Down
48 changes: 48 additions & 0 deletions .changelog/v0.8.x.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# v0.8.x

## Added
- 12 shared server utilities (`paths`, `downloadImage`, `parseYear`, `lifespan`, `validation`, `asyncHandler`, `sseHelpers`, `operationTracker`, `resolveCanonical`, `browserConnect`, `applyOverrides`, `batchFetchPersons`)
- `useBrowserConnection` and `useSSE` client hooks for deduplication
- Path traversal defense-in-depth across all file-serving endpoints
- FTS5 query sanitization for search
- CORS origin restriction via `CORS_ORIGIN` env var
- Request body whitelisting on provider/browser routes
- URL validation replacing string `includes()` checks
- `--dry-run` flag for purge script
- AbortController cleanup on PersonDetail navigation
- PWA support: favicon, manifest, apple-touch-icon, theme-color

## Changed
- CI no longer auto-increments version on push to dev
- Release workflow no longer bumps version after release (changelog archiving preserved)
- CI permissions downgraded from `contents: write` to `contents: read`
- `process.exit(1)` in fetcher replaced with typed error
- ID mapping cache changed from FIFO to LRU eviction
- AI discovery runs bounded with MAX_STORED_RUNS limit
- Path finding guarded against infinite loops
- Error handler now logs stack traces
- `requestTimeout` middleware wired up
- `Person.parents` type corrected to `(string | null)[]`
- Scripts standardized on `import.meta.dirname` and shared types

## Fixed
- `person_computed` view multi-row bug in vital event joins
- `typeof gen !== '?'` bug in logPerson
- Stale closures in IntegrityPage loader functions
- D3 zoom cleanup missing in SparseTreePage
- `useSocket` spread in deps array causing re-renders
- `useSocketConnection` returning stale snapshot instead of reactive state
- Dead state (`setScrapedData`, `setImportFile`) removed
- Safe JSON.parse on localStorage in PersonDetail
- Purge script whole-token matching (prevents partial ID matches)
- Migration script wrapped in transaction

## Removed
- 20+ duplicate `DATA_DIR` declarations across services
- 3 duplicate `downloadImage` implementations
- 7 duplicate SSE header setup blocks
- 15 duplicate ULID validation blocks in person routes
- 3 duplicate browser connection blocks
- 3 duplicate operation tracker implementations
- 6 duplicate photo-serve route handlers
- Duplicate `BrowserStatus` interface in IndexerPage
40 changes: 1 addition & 39 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ concurrency:
cancel-in-progress: true

permissions:
contents: write
contents: read

jobs:
build:
Expand Down Expand Up @@ -151,41 +151,3 @@ jobs:
name: scraper-test-results
path: test-results/
retention-days: 7

bump-version:
name: Bump Version
runs-on: ubuntu-latest
needs: [unit-tests, integration-tests, scraper-tests]
# Only on push to dev, not PRs, and only if all tests passed
if: |
github.event_name == 'push' &&
github.ref == 'refs/heads/dev' &&
!contains(github.event.head_commit.message, '[skip ci]')

steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Bump patch version
run: |
CURRENT_VERSION=$(node -p "require('./package.json').version")
MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
MINOR=$(echo $CURRENT_VERSION | cut -d. -f2)
PATCH=$(echo $CURRENT_VERSION | cut -d. -f3)
NEW_PATCH=$((PATCH + 1))
NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH"

npm version $NEW_VERSION --no-git-tag-version
cd shared && npm version $NEW_VERSION --no-git-tag-version && cd ..
cd client && npm version $NEW_VERSION --no-git-tag-version && cd ..
cd server && npm version $NEW_VERSION --no-git-tag-version && cd ..

git add package.json package-lock.json shared/package.json client/package.json server/package.json
git commit -m "build: bump version to $NEW_VERSION [skip ci]"
git push
18 changes: 1 addition & 17 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,14 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Prep dev branch for next release
- name: Archive changelog on dev branch
if: steps.tag-check.outputs.exists == 'false'
run: |
# Get current version (the one we just released)
CURRENT_VERSION=${{ steps.package-version.outputs.version }}
MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
MINOR=$(echo $CURRENT_VERSION | cut -d. -f2)
MAJOR_MINOR="$MAJOR.$MINOR"

# Increment minor, reset patch to 0
NEW_MINOR=$((MINOR + 1))
NEW_VERSION="$MAJOR.$NEW_MINOR.0"

# Checkout dev branch
git fetch origin dev
git checkout dev
Expand Down Expand Up @@ -143,14 +138,3 @@ jobs:
git push origin main
git checkout dev
fi

# Update package.json files for next version
npm version $NEW_VERSION --no-git-tag-version
cd shared && npm version $NEW_VERSION --no-git-tag-version && cd ..
cd client && npm version $NEW_VERSION --no-git-tag-version && cd ..
cd server && npm version $NEW_VERSION --no-git-tag-version && cd ..

# Commit and push version bump
git add package.json package-lock.json shared/package.json client/package.json server/package.json
git commit -m "build: prep v$NEW_VERSION for next release [skip ci]"
git push origin dev
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ client/public/playwright-report/

# Screenshots (may contain personal family data)
images/
.playwright-mcp
.playwright-mcp

# Terminal themes
.ghostty-theme
9 changes: 8 additions & 1 deletion client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SparseTree</title>
<meta name="theme-color" content="#3b82f6" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="SparseTree" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href="/manifest.json" />
<script>
// Apply theme class immediately to prevent flash
(function() {
Expand Down
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fsf/client",
"version": "0.7.12",
"version": "0.8.3",
"type": "module",
"scripts": {
"dev": "vite --port 6373",
Expand Down
Binary file added client/public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/favicon.ico
Binary file not shown.
55 changes: 55 additions & 0 deletions client/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/public/icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions client/public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "SparseTree",
"short_name": "SparseTree",
"description": "Genealogy toolkit for browsing and visualizing your family tree",
"start_url": "/",
"display": "standalone",
"background_color": "#0f1f33",
"theme_color": "#3b82f6",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
5 changes: 5 additions & 0 deletions client/src/components/favorites/SparseTreePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,11 @@ export function SparseTreePage() {
);
}

return () => {
if (svgRef.current) {
d3.select(svgRef.current).on('.zoom', null);
}
};
}, [treeData, theme]);

const handleZoomIn = () => {
Expand Down
Loading
Loading