Repository navigation
Release v3.5.9: Workspace modes, resilient search & AI, custom endpoints, and policy pages #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
d80d41b
4f30fc6
f1c226b
7780620
85404c4
2ef3e1a
59f7659
2237b69
4611312
a9ff669
2332b20
4c9d3df
b0a1664
dc867d0
167c6ca
32d4080
13cbbd3
28c8aae
66e2ffb
2628a4d
28e07d5
7440d1e
af988b7
0fe8043
6bc13c0
700c201
c0620c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,36 +1,56 @@ | ||
| # GitHub API (optional, increases rate limits for public repos) | ||
| GITHUB_TOKEN= | ||
|
|
||
| # AI provider: gemini | openai | anthropic | edgeone | mock | ||
| # AI provider: gemini | openai | anthropic | mock | ||
| AI_PROVIDER=mock | ||
| # Optional separate provider for semantic search: openai, gemini, or mock. | ||
| # EMBEDDING_PROVIDER=openai | ||
| # Independent embedding credentials and endpoint (recommended). | ||
| # Legacy OPENAI_/GEMINI_ settings are used when these are absent. | ||
| # EMBEDDING_API_KEY= | ||
| # EMBEDDING_API_BASE=https://api.openai.com/v1 | ||
| # EMBEDDING_MODEL=text-embedding-3-small | ||
| # OpenAI-compatible example: OPENAI_API_BASE=https://api.featherless.ai/v1 | ||
| # OPENAI_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-8B | ||
| # EMBEDDING_DIMENSIONS=4096 | ||
|
|
||
| # AI API Key (mandatory) | ||
| GEMINI_API_KEY= | ||
| OPENAI_API_KEY= | ||
| ANTHROPIC_API_KEY= | ||
| EDGEONE_API_KEY= | ||
|
|
||
| # Model overrides (optional) | ||
| GEMINI_MODEL=gemini-2.5-flash | ||
| GEMINI_API_VERSION=v1alpha | ||
| OPENAI_MODEL=gpt-4o-mini | ||
| ANTHROPIC_MODEL=claude-3-5-haiku-latest | ||
| EDGEONE_MODEL=@makers/deepseek-v4-flash | ||
|
|
||
| # Provider API base URL overrides (optional) | ||
| OPENAI_API_BASE= | ||
| ANTHROPIC_API_BASE= | ||
| EDGEONE_API_BASE=https://ai-gateway.edgeone.link/v1 | ||
|
|
||
| # Embedding overrides (optional) | ||
| OPENAI_EMBEDDING_MODEL=openrouter/openai/text-embedding-3-large | ||
| EDGEONE_EMBEDDING_MODEL=openrouter/openai/text-embedding-3-large | ||
| GEMINI_EMBEDDING_MODEL=gemini-embedding-001 | ||
| EMBEDDING_DIMENSIONS=3072 | ||
|
|
||
| # Cache key hashing secret (optional, set a stable random value in production) | ||
| # Required in shared mode (including when Redis is configured). Use a random secret. | ||
| # Local mode generates a process-only secret when this is blank. | ||
| TOKEN_CACHE_HASH_SECRET= | ||
|
|
||
| # Production server binding (optional) | ||
| HOST=0.0.0.0 | ||
| PORT=3000 | ||
|
|
||
| # Daily embedding input budget (300 MB; non-refundable reservation per attempt). | ||
| # In the default local mode this budget is PER-PROCESS: each instance enforces its own 300 MB. | ||
| # To share one budget across instances, use shared-mode rate limiting: | ||
| # RATE_LIMIT_MODE=shared plus UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN. | ||
| SERVER_EMBEDDING_DAILY_BYTES=300000000 | ||
|
|
||
| API_REQUESTS_PER_MINUTE=600 | ||
|
|
||
| SERVER_AI_DAILY_CALLS=500 | ||
|
|
||
| API_REQUESTS_PER_IP_PER_MINUTE=120 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,7 @@ | |
|
|
||
| ## Project Identity | ||
|
|
||
| **gitSdm** (Git Software Dependency Map) — v3.0.0. Graph-first repository analysis tool: visualize file dependencies, AI-powered codebase insights, semantic search, commit timelines, architecture diagrams, and dependency health. Single-page app with an embedded Express backend + Vercel serverless functions. | ||
| **gitSdm** (Git Software Dependency Map) — v3.5.11. Interactive repository dependency visualization tool: map file dependencies, AI-powered codebase insights, semantic search, commit timelines, architecture diagrams, and dependency health. Single-page app with an embedded Express backend + Vercel serverless functions. | ||
|
|
||
| --- | ||
|
|
||
|
|
@@ -20,7 +20,7 @@ | |
| | Graph Viz | react-force-graph-2d, d3-force, d3-hierarchy | | ||
| | Diagrams | Mermaid 11, html-to-image, jsPDF | | ||
| | Backend | Express (dev + prod server), Zod validation | | ||
| | AI Providers | Gemini, OpenAI, Anthropic, EdgeOne Makers, Mock — unified via `createProvider()` | | ||
| | AI Providers | Gemini, OpenAI, Anthropic, Mock — unified via `createProvider()` | | ||
| | GitHub API | Octokit REST v21 | | ||
| | Search | In-memory vector store with chunking + embedding + QA engine | | ||
| | Security | dompurify (sanitization) | | ||
|
|
@@ -35,15 +35,15 @@ | |
| gitSdm/ | ||
| ├── api/ # Vercel serverless entry points (thin wrappers) | ||
| │ ├── ai/ # AI endpoint wrappers | ||
| │ ├── repo/ # Repo API endpoint wrappers | ||
| │ ├── repo/ # Repo API endpoint wrappers (analyze, files, branches, churn, health) | ||
| │ └── trending.ts # Trending repos endpoint | ||
| ├── server/ # Backend services & router | ||
| │ ├── ai/ # AI provider abstraction + task handlers | ||
| │ ├── ai/ # AI provider abstraction, chat config, SSRF protection, prompts & tasks | ||
| │ │ ├── prompts.ts # Shared AI prompt templates | ||
| │ │ ├── provider.ts/test.ts # AI provider (Gemini/OpenAI/Anthropic/EdgeOne/Mock) | ||
| │ │ ├── provider.ts/test.ts # AI provider (Gemini/OpenAI/Anthropic/Mock) | ||
| │ │ ├── service.ts/test.ts # AI service orchestration | ||
| │ │ └── tasks/ # Individual AI tasks (diagram, explain, onboarding, playground, refactor) | ||
| │ ├── cache/ # LRU caching layer (lru.ts/test.ts) | ||
| │ ├── cache/ # LRU caching layer & hashed token secrets | ||
| │ ├── config/ # Env validation & public config (app-config.ts/test.ts) | ||
| │ ├── env.ts # Environment variable exports | ||
| │ ├── github/ # GitHub API client (Octokit), fetch-tree, mock-data (+ test files) | ||
|
|
@@ -53,51 +53,51 @@ gitSdm/ | |
| │ │ ├── dependency-analyzer.ts/test.ts | ||
| │ │ ├── file-classifier.ts/test.ts | ||
| │ │ ├── import-resolver.ts/test.ts | ||
| │ │ └── manifest-parsers/ # docker, go, java, npm, pip, rust + shared registry/types | ||
| │ │ └── manifest-parsers/ # docker, go, java, npm, pip (PEP 621/Poetry), rust + shared registry/types | ||
| │ ├── router/ # Route handlers (ai-routes, repo-routes, search-routes, schemas) | ||
| │ ├── search/ # Semantic search: chunker, embeddings, vector store, QA engine, indexing pipeline | ||
| │ ├── services/ # Business logic (analyze-repo, churn-service, dependency-health, get-file, npm-registry, trending) | ||
| │ ├── utils/ # Errors, context, logger, HTTP helpers | ||
| │ ├── search/ # Semantic search: chunker, embeddings, checkpoints, vector store, QA engine, indexing pipeline | ||
| │ ├── services/ # Business logic (analyze-repo, churn-service, dependency-health, repo-enrichment, get-file, npm-registry, trending) | ||
| │ ├── utils/ # Errors, context, logger, HTTP, limits, SSRF guard, bounded queue | ||
| │ ├── api-router.ts # Unified API router | ||
| │ ├── dev-api.ts # Dev server API middleware | ||
| │ ├── dev-api.ts # Vite dev server middleware | ||
| │ ├── prod-server.ts # Production Express server | ||
| │ └── vercel-handler.ts # Vercel serverless entry | ||
| ├── src/ # Frontend SPA | ||
| │ ├── app/ # Router setup (router.tsx), app providers (providers.tsx) | ||
| │ ├── components/ # UI components organized by domain | ||
| │ │ ├── ui/ # shadcn primitives & Base UI wrappers | ||
| │ │ ├── ui/ # shadcn primitives, button-variants & Base UI wrappers | ||
| │ │ ├── viz/ # Main workspace: ai-sidebar/, architecture/, layout/, learning-path/, top-nav/ | ||
| │ │ │ ├── ai-sidebar/ # AI center tab, action buttons, intelligence cards, tool cards | ||
| │ │ │ ├── architecture/ # Mermaid diagram generation, pan/zoom, render-sequence guard | ||
| │ │ │ ├── layout/ # VizSidebar & panel drawers | ||
| │ │ │ ├── learning-path/# Guided code walkthroughs | ||
| │ │ │ ├── top-nav/ # TopNav, BranchSwitcher, HeaderActionMenu, HeaderStats, WorkspaceModeSelector | ||
| │ │ │ ├── AIErrorCard.tsx, AISidebar.tsx, AnalysisTab.tsx, ArchitectureView.tsx | ||
| │ │ │ ├── BottomStatusBar.tsx, DependencyHealthTab.tsx, LearningPathTab.tsx | ||
| │ │ │ ├── OverviewTab.tsx, SettingsPopover.tsx, StagedLoader.tsx, VizError.tsx | ||
| │ │ │ ├── BottomStatusBar.tsx, ChurnStatus.tsx, DependencyHealthTab.tsx, LearningPathTab.tsx | ||
| │ │ │ ├── MotionSettings.tsx, OverviewTab.tsx, SettingsPopover.tsx, StagedLoader.tsx, VizError.tsx | ||
| │ │ ├── explorer/ # File explorer sidebar + code inspector dock | ||
| │ │ ├── timeline/ # Commit history view + repo timeline | ||
| │ │ ├── contributors/# Contributor analytics | ||
| │ │ ├── home/ # Landing page: HeroSection, RepoInput, HomeGraphPreview, Trending, repoPresets | ||
| │ │ ├── layout/ # Navbar | ||
| │ │ ├── contributors/# Contributor analytics & timeline layout | ||
| │ │ ├── home/ # Landing page: HeroSection, RepoInput, HomeGraphPreview, Trending, repoPresets, repo-navigation | ||
| │ │ ├── layout/ # Navbar, SiteFooter, InfoPageLayout, PageMetadata | ||
| │ │ ├── theme/ # ThemeSync | ||
| │ │ └── ErrorBoundary.tsx | ||
| │ ├── features/ # Feature modules | ||
| │ │ ├── graph/ # Graph canvas (ForceGraphCanvas, GraphCanvas, ToolbarDropdowns), widgets, force engine | ||
| │ │ │ ├── canvas/ # Canvas layout engine, hooks, helpers (filters), widgets (DropdownPanel, LegendPanel) | ||
| │ │ │ └── force/ # Force constants, color palettes, blastRadius, buildForceGraphData | ||
| │ │ ├── ai/ # AI task frontend hooks (useAiTasks) | ||
| │ │ └── search/ # Semantic search UI: SearchBar, SearchResults, QAAnswerView, IndexingStatusPanel | ||
| │ ├── hooks/ # Shared hooks (useAnalyzeRepo, useCodeInspectorState, useMobile, useRepoBranches, useRepoTags, useWorkspaceShortcuts) | ||
| │ ├── lib/ # Shared utilities: apiClient, clipboard, utils, file-context (+ test files) | ||
| │ ├── stores/ # Zustand stores (vizStore — canonical global store) | ||
| │ ├── pages/ # Route pages (VizPage, HomePage, SearchPage, NotFoundPage) | ||
| │ ├── types/ # TypeScript type definitions (api, domain, github, index) | ||
| │ │ │ └── force/ # Force constants, color palettes, blastRadius, buildForceGraphData, reconcileGraph | ||
| │ │ ├── ai/ # AI task frontend hooks & task cache (useAiTasks, tool-cache) | ||
| │ │ └── search/ # Semantic search UI: SearchBar, SearchResults, SearchIndexControls, SearchEmptyState, QAAnswerView, IndexingStatusPanel | ||
| │ ├── hooks/ # Shared hooks (useAnalyzeRepo, useCodeInspectorState, useMobile, useRepoBranches, useRepoTags, useWorkspaceShortcuts, useMotionPreference, useRepoChurn, useRepoHealth) | ||
| │ ├── lib/ # Shared utilities: apiClient, clipboard, utils, file-context, motion-preference, page-metadata, churn-progress, workspace-mode (+ test files) | ||
| │ ├── stores/ # Zustand stores (vizStore, motionStore, chatConfigStore) | ||
| │ ├── pages/ # Route pages (HomePage, VizPage, SearchPage, TermsPage, PrivacyPage, NotFoundPage, search-page-logic) | ||
| │ ├── types/ # TypeScript type definitions (api, domain, github, churn, index) | ||
| │ ├── styles/ # Tailwind CSS global styles (globals.css, interface.css) | ||
| │ └── main.tsx # App entry point | ||
| ├── e2e/ # Playwright end-to-end test specs (offline mock-driven) | ||
| └── public/ # Static assets | ||
| ``` | ||
| ├── public/ # Static assets (og-image.png/svg, robots.txt, sitemap.xml) | ||
| ├── scripts/ # Prerender and maintenance scripts (prerender.tsx, clean_graphify.py) | ||
| └── e2e/ # Playwright end-to-end test specs (offline mock-driven) | ||
|
|
||
| --- | ||
|
|
||
|
|
@@ -108,7 +108,7 @@ gitSdm/ | |
| All AI interactions go through `server/ai/provider.ts`. Do NOT call SDKs directly in task code. | ||
|
|
||
| ```text | ||
| Task handler → summarizer / task → createProvider(type) → { Gemini | OpenAI | Anthropic | EdgeOne | Mock } | ||
| Task handler → summarizer / task → createProvider(type) → { Gemini | OpenAI | Anthropic | Mock } | ||
| ``` | ||
|
|
||
| - Uses `createProvider(overrideKey?)` → returns `AIProvider` with `.complete(messages, options?)` | ||
|
|
@@ -133,7 +133,7 @@ Manual pathname-matching pattern in `server/router/`. Route files export `handle | |
|
|
||
| ### API Client (Frontend) | ||
|
|
||
| `src/lib/apiClient.ts` — Typed fetch wrapper via `apiFetch<T>(url, options?)`. Authentication tokens stored in `localStorage` (`gitsdm_gemini_api_key`, `gitsdm_github_pat`) and sent as `X-Gemini-API-Key` / `X-GitHub-Token` headers. | ||
| `src/lib/apiClient.ts` — Typed fetch wrapper via `apiFetch<T>(url, options?)`. Authentication tokens stored in `localStorage` (`gitsdm_gemini_api_key`, `gitsdm_github_pat`) and sent as `X-AI-API-Key` (with `X-Gemini-API-Key` fallback) / `X-GitHub-Token` headers. | ||
|
|
||
| ### Toast Notification Pattern | ||
|
|
||
|
|
@@ -189,7 +189,7 @@ Test runner: **Bun** (`bun test --isolate`). | |
|
|
||
| ### Coverage & Test Counts | ||
|
|
||
| - **46 test files, 408 tests passing** (991 expect calls), 0 failures. | ||
| - **78 test files, 527 tests passing** (1479 expect calls), 0 failures. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Custom agent: Flag AI Slop and Fabricated Changes This added test-count claim is stale: the checkout has 79 unit-test files and 11 E2E specs with 42 E2E tests, while this line and the E2E section report different totals. Run the current suites and update all documented counts together. Prompt for AI agents |
||
| - Run a single test file: `bun test src/components/home/RepoInput.test.ts` | ||
| - Run test coverage: `bun test --coverage` | ||
|
|
||
|
|
@@ -225,22 +225,18 @@ bun run lint # ESLint check | |
| | Variable | Default | Description | | ||
| | ------------------------ | ------------------------------------------ | -------------------------------------- | | ||
| | `GITHUB_TOKEN` | — | GitHub PAT for API rate limits | | ||
| | `AI_PROVIDER` | `mock` | Provider: gemini, openai, anthropic, edgeone, mock | | ||
| | `AI_PROVIDER` | `mock` | Provider: gemini, openai, anthropic, mock | | ||
| | `GEMINI_API_KEY` | — | Gemini API key | | ||
| | `OPENAI_API_KEY` | — | OpenAI API key | | ||
| | `ANTHROPIC_API_KEY` | — | Anthropic API key | | ||
| | `EDGEONE_API_KEY` | — | EdgeOne Makers Models API key (alias: `MAKERS_MODELS_KEY`) | | ||
| | `OPENAI_API_BASE` | OpenAI default | Custom API base URL | | ||
| | `ANTHROPIC_API_BASE` | Anthropic default | Custom API base URL | | ||
| | `EDGEONE_API_BASE` | `https://ai-gateway.edgeone.link/v1` | EdgeOne API base URL | | ||
| | `OPENAI_EMBEDDING_MODEL` | `openrouter/openai/text-embedding-3-large` | Embedding model | | ||
| | `EDGEONE_EMBEDDING_MODEL`| `openrouter/openai/text-embedding-3-large` | Embedding model | | ||
| | `EMBEDDING_DIMENSIONS` | `3072` | Vector dimension count | | ||
| | `GEMINI_MODEL` | `gemini-2.5-flash` | Gemini model override | | ||
| | `GEMINI_API_VERSION` | `v1alpha` | Gemini API version | | ||
| | `OPENAI_MODEL` | `gpt-4o-mini` | OpenAI model override | | ||
| | `ANTHROPIC_MODEL` | `claude-3-5-haiku-latest` | Anthropic model override | | ||
| | `EDGEONE_MODEL` | `@makers/deepseek-v4-flash` | EdgeOne model override | | ||
| | `GEMINI_EMBEDDING_MODEL` | `gemini-embedding-001` | Gemini embedding model override | | ||
| | `TOKEN_CACHE_HASH_SECRET`| — | Cache key hashing secret (production) | | ||
| | `HOST` | `0.0.0.0` | Production server bind | | ||
|
|
@@ -257,8 +253,32 @@ bun run lint # ESLint check | |
| - Zero hardcoded secrets | ||
| - 250+ LOC ceiling approached only by generated shadcn components | ||
|
|
||
| ## Versioning Policy | ||
|
|
||
| Version numbers increment progressively based on commit scope and change size: | ||
|
|
||
| - **Major (`+1.x.x`)**: Major milestone or large-scale overhaul (100+ files). | ||
| - **Minor (`x.+1.x`)**: Feature additions and substantial enhancements (`feat`). | ||
| - **Patch (`x.x.+1`)**: Bug fixes, security hardening, and maintenance (`fix`, `chore`). | ||
|
|
||
| Track progressive increments across commit batches rather than collapsing multiple feature commits into a single minor bump. Releases on the same date are consolidated in the changelog under that date's latest version. | ||
|
|
||
| ## CI Requirements | ||
|
|
||
| - `.github/workflows/ci.yml`: Pinned Bun 1.3.14 (`setup-bun`), `permissions: contents: read`. | ||
| - All installs use `nick-invision/retry@v3` with `bun install --frozen-lockfile`. | ||
| - Jobs: `lint` -> `typecheck` -> `test` -> `build` (with 2.5 MB gzipped-JS bundle gate) -> `e2e` (`AI_PROVIDER=mock`). | ||
|
|
||
| ## Agent skills | ||
|
|
||
| ### Issue tracker | ||
|
|
||
| Issues live as local markdown files under `.scratch/`. See `docs/agents/issue-tracker.md`. | ||
|
|
||
| ### Triage labels | ||
|
|
||
| Default five canonical triage roles. See `docs/agents/triage-labels.md`. | ||
|
|
||
| ### Domain docs | ||
|
|
||
| Single-context layout (`CONTEXT.md` + `docs/adr/`). See `docs/agents/domain.md`. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: The new OpenAI-compatible example duplicates two variable names already defined later in this same file: it proposes
# OPENAI_EMBEDDING_MODEL=Qwen/Qwen3-Embedding-8Band# EMBEDDING_DIMENSIONS=4096, while lines 33-35 still declareOPENAI_EMBEDDING_MODEL=openrouter/openai/text-embedding-3-largeandEMBEDDING_DIMENSIONS=3072. A user following the example by uncommenting the top block will have both assignments in the file, and the later ones win when the env is loaded (server/env.ts uses Vite loadEnv/dotenv, last assignment wins), so the Qwen/4096 settings are silently ignored. Worse, if onlyEMBEDDING_DIMENSIONS=4096is uncommented whiletext-embedding-3-largestays active, the 4096 output dimensionality exceeds that model's 3072 maximum and embedding calls fail. Make the example self-contained: have it reference theEMBEDDING_MODEL=/EMBEDDING_DIMENSIONS=pair only once, and add an explicit note that the legacyOPENAI_EMBEDDING_MODEL/EMBEDDING_DIMENSIONSlines below must be removed or commented out, or drop the duplicated variables from the example entirely.Prompt for AI agents