- Extend indexing_jobs schema to support 'paused' and 'cancelled' status
- Add JobQueue methods: pauseJob(), resumeJob(), cancelJob()
- Create POST /api/v1/jobs/[id]/{pause,resume,cancel} endpoints
- Implement /admin/jobs page with auto-refresh (3s polling)
- Add JobStatusBadge component with color-coded status display
- Action buttons appear contextually based on job status
- Optimistic UI updates with error handling
- All 477 existing tests pass, no regressions
- Fix schema.test.ts: use Unix timestamp integers instead of Date objects for snippet_embeddings.createdAt
- Fix embedding.service.test.ts: use 'local-default' profile instead of non-existent 'test-profile', remove require() calls and use proper ESM imports
- Fix hybrid.search.service.test.ts: update VectorSearch.vectorSearch() calls to use options object instead of positional parameters, remove manual FTS insert (triggers handle it automatically)
- Fix migration 0002: improve SQL formatting with line breaks after statement-breakpoint comments
All 459 tests now passing (18 skipped).
- Add embedding_profiles table with provider registry pattern
- Install @xenova/transformers as runtime dependency
- Update snippet_embeddings with composite PK (snippet_id, profile_id)
- Seed default local profile using Xenova/all-MiniLM-L6-v2
- Add provider registry (local-transformers, openai-compatible)
- Update EmbeddingService to persist and retrieve by profileId
- Add version-scoped VectorSearch with optional versionId filtering
- Add searchMode (auto|keyword|semantic|hybrid) to HybridSearchService
- Update API /context route to load active profile, support searchMode/alpha params
- Extend MCP query-docs tool with searchMode and alpha parameters
- Update settings API to work with embedding_profiles table
- Add comprehensive test coverage for profiles, registry, version scoping
Status: 445/451 tests passing, core feature complete
onMount is Svelte 4 idiom. In Svelte 5 runes mode $effect is the correct
primitive for side effects and it provides additional behaviour onMount
cannot:
- IndexingProgress: $effect re-runs when jobId prop changes, restarting
the polling loop for the new job. onMount would have missed prop changes.
- search/+page.svelte: $effect with untrack() reads page.url params once
on mount without tracking the URL as a reactive dependency, preventing
goto() calls inside searchDocs() from triggering an infinite re-run loop.
Restores the page store import from $app/state.
- settings/+page.svelte: $effect with no reactive reads in the body runs
exactly once on mount — equivalent to onMount but idiomatic Svelte 5.
All three verified with svelte-autofixer: no issues.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
$effect runs during SSR and re-runs on every reactive dependency change,
causing polling loops and URL reads to fire at the wrong time. onMount
runs once on the client after first render, which is the correct lifecycle
for polling, URL param reads, and async data loads.
- IndexingProgress: polling loop now starts on mount, not on reactive trigger
- search/+page.svelte: URL param init moved to onMount; use window.location
directly instead of the page store to avoid reactive re-runs
- settings/+page.svelte: config load and local provider probe moved to onMount
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace ad-hoc inline row casting (snake_case → camelCase) spread across
services, routes, and the indexing pipeline with explicit model classes
(Repository, IndexingJob, RepositoryVersion, Snippet, SearchResult) and
dedicated mapper classes that own the DB → domain conversion.
- Add src/lib/server/models/ with typed model classes for all domain entities
- Add src/lib/server/mappers/ with mapper classes per entity
- Remove duplicated RawRow interfaces and inline map functions from
job-queue, repository.service, indexing.pipeline, and all API routes
- Add dtoJsonResponse helper to standardise JSON responses via SvelteKit json()
- Add api-contract.integration.test.ts as a regression baseline
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix Svelte state_referenced_locally warning in +page.svelte and repos/[id]/+page.svelte
by initializing $state with empty defaults and syncing via $effect
- Add FolderPicker component with server-side filesystem browser
(single-click to navigate, double-click or "Select This Folder" to confirm)
- Git repos highlighted with orange folder icon and "git" badge
- Add GET /api/v1/fs/browse endpoint listing subdirectories
- Wire FolderPicker into AddRepositoryModal for local source type
- Auto-fills title from the selected folder name
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- computeDiff classifies files into added/modified/deleted/unchanged buckets
- Only changed and new files are parsed and re-embedded on re-runs
- Deleted files removed atomically from DB
- Progress counts all files including unchanged for accurate reporting
- ~20x speedup for re-indexing large repositories with few changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Repository list with state badges, stats, and action buttons
- Add repository modal for GitHub URLs and local paths
- Live indexing progress bar polling every 2s
- Confirm dialog for destructive actions
- Repository detail page with versions and recent jobs
- Settings page placeholder
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- VersionService with list, add, remove, getByTag, registerFromConfig
- GitHub tag discovery helper for validating tags before indexing
- Version ID format: /owner/repo/tag (e.g. /facebook/react/v18.3.0)
- GET/POST /api/v1/libs/:id/versions
- DELETE /api/v1/libs/:id/versions/:tag
- POST /api/v1/libs/:id/versions/:tag/index
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Lenient parser for trueref.json and context7.json (trueref.json takes precedence)
- Validates folders, excludeFolders, excludeFiles, rules, previousVersions
- Stores config in repository_configs table
- JSON Schema served at GET /api/v1/schema/trueref-config.json for IDE validation
- Rules injected at top of every query-docs response
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SQLite-backed job queue with sequential processing and startup recovery
- Atomic snippet replacement in single transaction
- context7-compatible GET /api/v1/libs/search and GET /api/v1/context
- Token budget limiting and JSON/txt response format support
- CORS headers on all API routes via SvelteKit handle hook
- Library ID parser supporting /owner/repo and /owner/repo/version
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BM25 ranking via SQLite FTS5 bm25() function
- Query preprocessor with wildcard expansion and special char escaping
- Library search with composite scoring (name match, trust score, snippet count)
- Trust score computation from stars, coverage, and source type
- Response formatters for library and snippet results
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Markdown parser with heading-based section splitting and code block extraction
- Code file parser with regex boundary detection for 10+ languages
- Sliding window chunker with configurable token limits and overlap
- Language detection from file extensions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GitHub crawler with rate limiting, semaphore concurrency, retry logic
- File filtering by extension, size, and trueref.json rules
- Local filesystem crawler with SHA-256 checksums and progress callbacks
- Shared types and file filter logic between both crawlers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the end-to-end indexing pipeline with a SQLite-backed job
queue, startup recovery, and REST API endpoints for job status.
- IndexingPipeline: orchestrates crawl → parse → atomic replace → embed
→ repo stats update with progress tracking at each stage
- JobQueue: sequential SQLite-backed queue (no external broker), deduplicates
active jobs per repository, drains queued jobs on startup
- startup.ts: stale job recovery (running→failed), repo state reset, singleton
initialization wired from hooks.server.ts
- GET /api/v1/jobs with repositoryId/status/limit filtering
- GET /api/v1/jobs/[id] single job lookup
- hooks.server.ts: initializes DB and pipeline on server start
- 18 unit tests covering queue, pipeline stages, recovery, and atomicity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add EmbeddingProvider interface with OpenAI-compatible, local (optional
@xenova/transformers via dynamic import), and Noop (FTS5-only fallback)
implementations. EmbeddingService batches requests and persists Float32Array
blobs to snippet_embeddings. GET/PUT /api/v1/settings/embedding endpoints
read and write embedding config from the settings table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add RepositoryService with full CRUD, ID resolution helpers, input
validation, six SvelteKit API routes (GET/POST /api/v1/libs,
GET/PATCH/DELETE /api/v1/libs/:id, POST /api/v1/libs/:id/index), and
37 unit tests covering all service operations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>