Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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.2",
"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