From b75235919e978ec611bcdddf7ae4ad7f2386dae7 Mon Sep 17 00:00:00 2001 From: Lum1104 Date: Sun, 15 Mar 2026 11:16:43 +0800 Subject: [PATCH] refactor: restructure monorepo into Claude Code plugin layout Move packages/{core,dashboard,skill} into understand-anything-plugin/ to conform to the Claude Code plugin format. Add .claude-plugin/marketplace.json for plugin discovery. Update workspace config and docs accordingly. Co-Authored-By: Claude Opus 4.6 --- .claude-plugin/marketplace.json | 16 + CLAUDE.md | 15 +- README.md | 255 +- .../dashboard/public/knowledge-graph.json | 528 --- pnpm-lock.yaml | 46 +- pnpm-workspace.yaml | 3 +- .../.claude-plugin/plugin.json | 0 .../agents/architecture-analyzer.md | 0 .../agents/file-analyzer.md | 0 .../agents/graph-reviewer.md | 0 .../agents/project-scanner.md | 0 .../agents/tour-builder.md | 0 .../package.json | 0 .../packages}/core/package.json | 0 .../src/__tests__/embedding-search.test.ts | 0 .../src/__tests__/language-lesson.test.ts | 0 .../core/src/__tests__/layer-detector.test.ts | 0 .../src/__tests__/plugin-discovery.test.ts | 0 .../src/__tests__/plugin-registry.test.ts | 0 .../core/src/__tests__/schema.test.ts | 0 .../core/src/__tests__/search.test.ts | 0 .../core/src/__tests__/staleness.test.ts | 0 .../core/src/__tests__/tour-generator.test.ts | 0 .../core/src/analyzer/graph-builder.test.ts | 0 .../core/src/analyzer/graph-builder.ts | 0 .../core/src/analyzer/language-lesson.ts | 0 .../core/src/analyzer/layer-detector.ts | 0 .../core/src/analyzer/llm-analyzer.test.ts | 0 .../core/src/analyzer/llm-analyzer.ts | 0 .../core/src/analyzer/tour-generator.ts | 0 .../packages}/core/src/embedding-search.ts | 0 .../packages}/core/src/index.ts | 0 .../packages}/core/src/persistence/index.ts | 0 .../core/src/persistence/persistence.test.ts | 0 .../packages}/core/src/plugins/discovery.ts | 0 .../packages}/core/src/plugins/registry.ts | 0 .../src/plugins/tree-sitter-plugin.test.ts | 0 .../core/src/plugins/tree-sitter-plugin.ts | 0 .../packages}/core/src/schema.ts | 0 .../packages}/core/src/search.ts | 0 .../packages}/core/src/staleness.ts | 0 .../packages}/core/src/types.test.ts | 0 .../packages}/core/src/types.ts | 0 .../packages/core}/tsconfig.json | 2 +- .../packages}/dashboard/index.html | 0 .../packages}/dashboard/package.json | 0 .../dashboard/public/knowledge-graph.json | 3088 +++++++++++++++++ .../packages}/dashboard/src/App.tsx | 0 .../dashboard/src/components/ChatPanel.tsx | 0 .../dashboard/src/components/CodeViewer.tsx | 0 .../dashboard/src/components/CustomNode.tsx | 0 .../dashboard/src/components/GraphView.tsx | 0 .../dashboard/src/components/LayerLegend.tsx | 0 .../dashboard/src/components/LearnPanel.tsx | 0 .../dashboard/src/components/NodeInfo.tsx | 0 .../src/components/PersonaSelector.tsx | 0 .../dashboard/src/components/SearchBar.tsx | 0 .../packages}/dashboard/src/index.css | 0 .../packages}/dashboard/src/main.tsx | 0 .../packages}/dashboard/src/store.ts | 0 .../packages}/dashboard/src/utils/layout.ts | 0 .../packages}/dashboard/src/vite-env.d.ts | 0 .../packages}/dashboard/tsconfig.app.json | 0 .../packages}/dashboard/tsconfig.json | 0 .../packages}/dashboard/vite.config.ts | 9 +- .../skills/understand-chat/SKILL.md | 0 .../skills/understand-diff/SKILL.md | 0 .../skills/understand-explain/SKILL.md | 0 .../skills/understand-onboard/SKILL.md | 0 .../skills/understand/SKILL.md | 0 .../src/__tests__/context-builder.test.ts | 0 .../src/__tests__/diff-analyzer.test.ts | 0 .../src/__tests__/explain-builder.test.ts | 0 .../src/__tests__/onboard-builder.test.ts | 0 .../src/context-builder.ts | 0 .../src/diff-analyzer.ts | 0 .../src/explain-builder.ts | 0 .../src/index.ts | 0 .../src/onboard-builder.ts | 0 .../src/understand-chat.ts | 0 .../tsconfig.json | 2 +- 81 files changed, 3303 insertions(+), 661 deletions(-) create mode 100644 .claude-plugin/marketplace.json delete mode 100644 packages/dashboard/public/knowledge-graph.json rename {packages/skill => understand-anything-plugin}/.claude-plugin/plugin.json (100%) rename {packages/skill => understand-anything-plugin}/agents/architecture-analyzer.md (100%) rename {packages/skill => understand-anything-plugin}/agents/file-analyzer.md (100%) rename {packages/skill => understand-anything-plugin}/agents/graph-reviewer.md (100%) rename {packages/skill => understand-anything-plugin}/agents/project-scanner.md (100%) rename {packages/skill => understand-anything-plugin}/agents/tour-builder.md (100%) rename {packages/skill => understand-anything-plugin}/package.json (100%) rename {packages => understand-anything-plugin/packages}/core/package.json (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/embedding-search.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/language-lesson.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/layer-detector.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/plugin-discovery.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/plugin-registry.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/schema.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/search.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/staleness.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/__tests__/tour-generator.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/analyzer/graph-builder.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/analyzer/graph-builder.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/analyzer/language-lesson.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/analyzer/layer-detector.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/analyzer/llm-analyzer.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/analyzer/llm-analyzer.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/analyzer/tour-generator.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/embedding-search.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/index.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/persistence/index.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/persistence/persistence.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/plugins/discovery.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/plugins/registry.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/plugins/tree-sitter-plugin.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/plugins/tree-sitter-plugin.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/schema.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/search.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/staleness.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/types.test.ts (100%) rename {packages => understand-anything-plugin/packages}/core/src/types.ts (100%) rename {packages/skill => understand-anything-plugin/packages/core}/tsconfig.json (71%) rename {packages => understand-anything-plugin/packages}/dashboard/index.html (100%) rename {packages => understand-anything-plugin/packages}/dashboard/package.json (100%) create mode 100644 understand-anything-plugin/packages/dashboard/public/knowledge-graph.json rename {packages => understand-anything-plugin/packages}/dashboard/src/App.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/ChatPanel.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/CodeViewer.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/CustomNode.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/GraphView.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/LayerLegend.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/LearnPanel.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/NodeInfo.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/PersonaSelector.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/components/SearchBar.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/index.css (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/main.tsx (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/store.ts (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/utils/layout.ts (100%) rename {packages => understand-anything-plugin/packages}/dashboard/src/vite-env.d.ts (100%) rename {packages => understand-anything-plugin/packages}/dashboard/tsconfig.app.json (100%) rename {packages => understand-anything-plugin/packages}/dashboard/tsconfig.json (100%) rename {packages => understand-anything-plugin/packages}/dashboard/vite.config.ts (68%) rename {packages/skill => understand-anything-plugin}/skills/understand-chat/SKILL.md (100%) rename {packages/skill => understand-anything-plugin}/skills/understand-diff/SKILL.md (100%) rename {packages/skill => understand-anything-plugin}/skills/understand-explain/SKILL.md (100%) rename {packages/skill => understand-anything-plugin}/skills/understand-onboard/SKILL.md (100%) rename {packages/skill => understand-anything-plugin}/skills/understand/SKILL.md (100%) rename {packages/skill => understand-anything-plugin}/src/__tests__/context-builder.test.ts (100%) rename {packages/skill => understand-anything-plugin}/src/__tests__/diff-analyzer.test.ts (100%) rename {packages/skill => understand-anything-plugin}/src/__tests__/explain-builder.test.ts (100%) rename {packages/skill => understand-anything-plugin}/src/__tests__/onboard-builder.test.ts (100%) rename {packages/skill => understand-anything-plugin}/src/context-builder.ts (100%) rename {packages/skill => understand-anything-plugin}/src/diff-analyzer.ts (100%) rename {packages/skill => understand-anything-plugin}/src/explain-builder.ts (100%) rename {packages/skill => understand-anything-plugin}/src/index.ts (100%) rename {packages/skill => understand-anything-plugin}/src/onboard-builder.ts (100%) rename {packages/skill => understand-anything-plugin}/src/understand-chat.ts (100%) rename {packages/core => understand-anything-plugin}/tsconfig.json (72%) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..91d65c2 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,16 @@ +{ + "version": 1, + "name": "understand-anything", + "description": "AI-powered codebase understanding — analyze, visualize, and explain any project", + "owner": { + "name": "Lum1104" + }, + "plugins": [ + { + "name": "understand-anything", + "description": "Multi-agent codebase analysis with interactive dashboard, guided tours, and skill commands", + "version": "1.0.0", + "source": "./understand-anything-plugin" + } + ] +} diff --git a/CLAUDE.md b/CLAUDE.md index 73ccc9e..e4d48e2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,9 +5,12 @@ An open-source tool combining LLM intelligence + static analysis to produce inte ## Architecture - **Monorepo** with pnpm workspaces -- **packages/core** — Shared analysis engine (types, persistence, tree-sitter plugin, LLM prompt templates) -- **packages/dashboard** — React + TypeScript web dashboard (React Flow, Monaco Editor, Zustand, TailwindCSS) -- **packages/skill** — Claude Code skills (`/understand-chat`, `/understand-diff`, `/understand-explain`, `/understand-onboard`) +- **understand-anything-plugin/** — Claude Code plugin containing all source code: + - **understand-anything-plugin/packages/core** — Shared analysis engine (types, persistence, tree-sitter plugin, LLM prompt templates) + - **understand-anything-plugin/packages/dashboard** — React + TypeScript web dashboard (React Flow, Monaco Editor, Zustand, TailwindCSS) + - **understand-anything-plugin/src** — Skill TypeScript source for `/understand-chat`, `/understand-diff`, `/understand-explain`, `/understand-onboard` + - **understand-anything-plugin/skills** — Skill definitions + - **understand-anything-plugin/agents** — Agent definitions ## Key Commands - `pnpm install` — Install all dependencies @@ -15,9 +18,9 @@ An open-source tool combining LLM intelligence + static analysis to produce inte - `pnpm --filter @understand-anything/core test` — Run core tests - `pnpm dev:dashboard` — Start dashboard dev server -## Key Commands (updated) -- `pnpm --filter @understand-anything/skill build` — Build skill package -- `pnpm --filter @understand-anything/skill test` — Run skill tests +## Key Commands (plugin) +- `pnpm --filter @understand-anything/skill build` — Build the plugin package +- `pnpm --filter @understand-anything/skill test` — Run plugin tests ## Phase 2 Features - Fuzzy search via Fuse.js (SearchEngine in core) diff --git a/README.md b/README.md index 9ff62b7..e3c838b 100644 --- a/README.md +++ b/README.md @@ -1,157 +1,206 @@ -# Understand Anything +

Understand Anything

-An open-source tool that combines LLM intelligence with static analysis to help anyone understand any codebase — from junior developers to product managers. +

+ Turn any codebase into an interactive knowledge graph you can explore, search, and ask questions about. +

-## Current Status +

+ Quick Start + License: MIT + Claude Code Plugin +

-**Phase 4 complete.** The core analysis engine, web dashboard, and Claude Code skills are all functional. The project includes a multi-agent `/understand` command, fuzzy and semantic search, schema validation, staleness detection, layer auto-detection, guided learning tours, and an interactive chat interface. +--- -## Features +**You just joined a new team. The codebase is 200,000 lines of code. Where do you even start?** -### Phase 1 — Foundation -- **Knowledge Graph** — Automatically maps your codebase into an interactive graph of files, functions, classes, and their relationships -- **Multi-Panel Dashboard** — Graph view, code viewer, chat, and learn panels in a workspace layout -- **Natural Language Search** — Search your codebase with plain English: "which parts handle authentication?" -- **Tree-sitter Analysis** — Accurate structural analysis for TypeScript, JavaScript (more languages coming) -- **LLM-Powered Summaries** — Every node gets a plain-English description of what it does and why +Understand Anything is a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugin that analyzes your project with a multi-agent pipeline, builds a knowledge graph of every file, function, class, and dependency, then gives you an interactive dashboard to explore it all visually. Stop reading code blind. Start seeing the big picture. -### Phase 2 — Intelligence -- **Fuzzy Search** — Fast, typo-tolerant search across all graph nodes via Fuse.js (SearchEngine in core) -- **Schema Validation** — Zod-based runtime validation when loading knowledge graphs, with detailed error messages -- **Staleness Detection** — Detects changed files via git diff and incrementally merges graph updates -- **Layer Auto-Detection** — Heuristic-based layer grouping (API, Service, Data, UI, Utility) with LLM refinement -- **`/understand-chat` Skill** — Ask questions about your codebase directly in the terminal via Claude Code -- **Dashboard Chat Panel** — Context-aware Q&A integrated into the web dashboard (Claude API) -- **Dagre Auto-Layout** — Automatic hierarchical graph layout for clean visualization -- **Layer Visualization** — Color-coded layer grouping with collapsible groups and a legend panel +--- -### Phase 3 — Learning -- **Guided Tours** — Auto-generated step-by-step walkthroughs of codebase architecture (Kahn's algorithm) -- **Language Lessons** — 12 concept patterns explained in context (generics, closures, decorators, etc.) -- **Persona Selector** — Adaptive UI for junior devs, non-technical stakeholders, and AI-assisted developers -- **Learn Panel** — Interactive tour mode with graph highlighting in the dashboard +## 🤔 Why? -### Phase 4 — Skills & Ecosystem -- **`/understand` Command** — Multi-agent pipeline that analyzes a codebase end-to-end and produces `knowledge-graph.json` -- **`/understand-diff` Skill** — Analyze git diffs against the knowledge graph for impact and risk assessment -- **`/understand-explain` Skill** — Deep-dive explanations of any file, function, or module -- **`/understand-onboard` Skill** — Generate team onboarding guides from the knowledge graph -- **Plugin Registry** — Community analyzer plugins with auto-discovery -- **Semantic Search** — Embedding-based vector search with cosine similarity +Reading code is hard. Understanding a whole codebase is harder. Documentation is always out of date, onboarding takes weeks, and every new feature feels like archaeology. -## Quick Start +Understand Anything fixes this by combining **LLM intelligence** with **static analysis** to produce a living, explorable map of your project — with plain-English explanations for everything. -### 1. Analyze any codebase (via Claude Code) +--- + +## 🎯 Who is this for? + + + + + + + +
+

👩‍💻 Junior Developers

+

Stop drowning in unfamiliar code. Get guided tours that walk you through the architecture step by step, with every function and class explained in plain English.

+
+

📋 Product Managers & Designers

+

Finally understand how the system actually works without reading code. Ask questions like "how does authentication work?" and get clear answers grounded in the real codebase.

+
+

🤖 AI-Assisted Developers

+

Give your AI tools deep context about your project. Use /understand-diff before code review, /understand-explain to dive into any module, or /understand-chat to reason about architecture.

+
+ +--- + +## 🚀 Quick Start + +### 1. Install the plugin ```bash -# Install the plugin -claude --plugin-dir /path/to/Understand-Anything/packages/skill +/plugin marketplace add Lum1104/Understand-Anything +/plugin install understand-anything +``` -# In any project, run: +### 2. Analyze your codebase + +```bash /understand ``` -This produces `.understand-anything/knowledge-graph.json` in your project. +A multi-agent pipeline scans your project, extracts every file, function, class, and dependency, then builds a knowledge graph saved to `.understand-anything/knowledge-graph.json`. -### 2. View the dashboard +### 3. Explore the dashboard ```bash -# Clone this repo and install -git clone https://github.com/Lum1104/Understand-Anything.git -cd Understand-Anything -pnpm install - -# Start the dashboard (auto-detects .understand-anything/ from your project) -pnpm dev:dashboard +/understand-dashboard ``` -The dashboard dev server automatically looks for `.understand-anything/knowledge-graph.json` in the project root — no manual copying needed. +An interactive web dashboard opens with your codebase visualized as a graph — color-coded by architectural layer, searchable, and clickable. Select any node to see its code, relationships, and a plain-English explanation. -### 3. Use other skill commands +### 4. Keep learning ```bash -# Ask questions about the codebase -/understand-chat How does authentication work in this project? +# Ask anything about the codebase +/understand-chat How does the payment flow work? -# Analyze impact of current changes +# Analyze impact of your current changes /understand-diff -# Deep-dive into a specific file +# Deep-dive into a specific file or function /understand-explain src/auth/login.ts -# Generate an onboarding guide +# Generate an onboarding guide for new team members /understand-onboard ``` -## Plugin Installation +--- -The skill commands work in any project via Claude Code: +## ✨ Features -```bash -# Option 1: Load for current session -claude --plugin-dir /path/to/Understand-Anything/packages/skill + + + + + + + + + + + + + + + + + +
+

🗺️ Interactive Knowledge Graph

+

Files, functions, classes, and their relationships visualized with React Flow. Click any node to see its code and connections.

+
+

💬 Plain-English Summaries

+

Every node described by an LLM so anyone — technical or not — can understand what it does and why it exists.

+
+

🧭 Guided Tours

+

Auto-generated walkthroughs of the architecture, ordered by dependency. Learn the codebase in the right order.

+
+

🔍 Fuzzy & Semantic Search

+

Find anything by name or by meaning. Search "which parts handle auth?" and get relevant results across the graph.

+
+

📊 Diff Impact Analysis

+

See which parts of the system your changes affect before you commit. Understand ripple effects across the codebase.

+
+

🎭 Persona-Adaptive UI

+

The dashboard adjusts its detail level based on who you are — junior dev, PM, or power user.

+
+

🏗️ Layer Visualization

+

Automatic grouping by architectural layer — API, Service, Data, UI, Utility — with color-coded legend.

+
+

📚 Language Concepts

+

12 programming patterns (generics, closures, decorators, etc.) explained in context wherever they appear.

+
-# Option 2: Add to .claude/settings.json for persistent use -# (in the project where you cloned Understand-Anything) +--- + +## 🔧 Under the Hood + +### Multi-Agent Pipeline + +The `/understand` command orchestrates 5 specialized agents: + +| Agent | Role | +|-------|------| +| `project-scanner` | Discover files, detect languages and frameworks | +| `file-analyzer` | Extract functions, classes, imports; produce graph nodes and edges | +| `architecture-analyzer` | Identify architectural layers | +| `tour-builder` | Generate guided learning tours | +| `graph-reviewer` | Validate graph completeness and referential integrity | + +File analyzers run in parallel (up to 3 concurrent). Supports incremental updates — only re-analyzes files that changed since the last run. + +### Project Structure + +``` +understand-anything-plugin/ + .claude-plugin/ — Plugin manifest + agents/ — Specialized AI agents + skills/ — Skill definitions (/understand, /understand-chat, etc.) + src/ — TypeScript source (context-builder, diff-analyzer, etc.) + packages/ + core/ — Analysis engine (types, persistence, tree-sitter, search, schema, tours) + dashboard/ — React + TypeScript web dashboard ``` -```json -{ - "enabledPlugins": { - "understand-anything": {} - } -} -``` +### Tech Stack -## Commands +TypeScript, pnpm workspaces, React 18, Vite, TailwindCSS, React Flow, Monaco Editor, Zustand, web-tree-sitter, Fuse.js, Zod, Dagre + +### Development Commands | Command | Description | |---------|-------------| | `pnpm install` | Install all dependencies | | `pnpm --filter @understand-anything/core build` | Build the core package | | `pnpm --filter @understand-anything/core test` | Run core tests | -| `pnpm --filter @understand-anything/skill build` | Build the skill package | -| `pnpm --filter @understand-anything/skill test` | Run skill tests | +| `pnpm --filter @understand-anything/skill build` | Build the plugin package | +| `pnpm --filter @understand-anything/skill test` | Run plugin tests | | `pnpm --filter @understand-anything/dashboard build` | Build the dashboard | | `pnpm dev:dashboard` | Start dashboard dev server | -## Multi-Agent Architecture +--- -The `/understand` command orchestrates 5 specialized agents in a 7-phase pipeline: +## 🤝 Contributing -| Agent | Model | Role | -|-------|-------|------| -| `project-scanner` | Haiku | Discover files, detect languages and frameworks | -| `file-analyzer` | Sonnet | Extract functions, classes, imports; produce graph nodes/edges | -| `architecture-analyzer` | Sonnet | Identify architectural layers (API, Service, Data, UI, etc.) | -| `tour-builder` | Sonnet | Generate guided learning tours | -| `graph-reviewer` | Haiku | Validate graph completeness and referential integrity | +Contributions are welcome! Here's how to get started: -File analyzers run in parallel (up to 3 concurrent) for speed. Supports incremental updates — only re-analyzes files that changed since the last run. +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/my-feature`) +3. Run the tests (`pnpm --filter @understand-anything/core test`) +4. Commit your changes and open a pull request -## Project Structure +Please open an issue first for major changes so we can discuss the approach. -``` -packages/ - core/ — Analysis engine: types, persistence, tree-sitter, search, schema, staleness, layers, tours - dashboard/ — React + TypeScript web dashboard with chat, learn, and persona panels - skill/ - agents/ — Specialized AI agents (scanner, analyzer, architect, tour-builder, reviewer) - skills/ — Claude Code skills (/understand, /understand-chat, /understand-diff, etc.) -``` +--- -## Tech Stack +

+ Stop reading code blind. Start understanding everything. +

-- TypeScript, pnpm workspaces -- React 18, Vite, TailwindCSS -- React Flow (graph visualization) -- Monaco Editor (code viewer) -- Zustand (state management) -- tree-sitter (static analysis) -- Fuse.js (fuzzy search) -- Zod (schema validation) -- Dagre (graph layout) - -## License - -MIT +

+ MIT License © Lum1104 +

diff --git a/packages/dashboard/public/knowledge-graph.json b/packages/dashboard/public/knowledge-graph.json deleted file mode 100644 index 9ced329..0000000 --- a/packages/dashboard/public/knowledge-graph.json +++ /dev/null @@ -1,528 +0,0 @@ -{ - "version": "1.0.0", - "project": { - "name": "taskflow-api", - "languages": ["typescript"], - "frameworks": ["express", "prisma", "zod"], - "description": "A task management REST API built with Express and Prisma. Supports user authentication, project workspaces, task CRUD with assignments, and real-time notifications via WebSocket. Designed for team collaboration with role-based access control.", - "analyzedAt": "2026-03-14T12:00:00.000Z", - "gitCommitHash": "a1b2c3d4e5f6" - }, - "nodes": [ - { - "id": "file:src/index.ts", - "type": "file", - "name": "index.ts", - "filePath": "src/index.ts", - "summary": "Application entry point. Initializes the Express server, applies middleware, mounts route handlers, and starts listening on the configured port.", - "tags": ["entry", "server", "express"], - "complexity": "moderate" - }, - { - "id": "file:src/routes/task.routes.ts", - "type": "file", - "name": "task.routes.ts", - "filePath": "src/routes/task.routes.ts", - "summary": "Defines REST endpoints for task CRUD operations: GET /tasks, POST /tasks, PATCH /tasks/:id, DELETE /tasks/:id. Validates request bodies with Zod schemas before delegating to TaskService.", - "tags": ["routes", "tasks", "rest"], - "complexity": "moderate" - }, - { - "id": "file:src/routes/auth.routes.ts", - "type": "file", - "name": "auth.routes.ts", - "filePath": "src/routes/auth.routes.ts", - "summary": "Authentication routes: POST /auth/login, POST /auth/register, POST /auth/refresh. Handles credential validation and JWT token issuance.", - "tags": ["routes", "auth", "jwt"], - "complexity": "moderate" - }, - { - "id": "file:src/routes/project.routes.ts", - "type": "file", - "name": "project.routes.ts", - "filePath": "src/routes/project.routes.ts", - "summary": "Project workspace endpoints: CRUD for projects plus member management. Enforces role-based access so only admins can modify project settings.", - "tags": ["routes", "projects", "rbac"], - "complexity": "moderate" - }, - { - "id": "file:src/services/task.service.ts", - "type": "file", - "name": "task.service.ts", - "filePath": "src/services/task.service.ts", - "summary": "Business logic for tasks. Handles creation, status transitions, assignment, due-date validation, and triggers notifications on state changes.", - "tags": ["service", "tasks", "business-logic"], - "complexity": "complex" - }, - { - "id": "func:src/services/task.service.ts:createTask", - "type": "function", - "name": "createTask", - "filePath": "src/services/task.service.ts", - "lineRange": [24, 58], - "summary": "Creates a new task in the database. Validates the assignee belongs to the project, sets default status to 'todo', and publishes a TASK_CREATED event to the notification service.", - "tags": ["create", "validation", "events"], - "complexity": "moderate" - }, - { - "id": "func:src/services/task.service.ts:transitionStatus", - "type": "function", - "name": "transitionStatus", - "filePath": "src/services/task.service.ts", - "lineRange": [60, 102], - "summary": "Moves a task through its lifecycle (todo -> in_progress -> review -> done). Enforces valid transitions and records the state change timestamp.", - "tags": ["state-machine", "workflow", "validation"], - "complexity": "complex" - }, - { - "id": "file:src/services/auth.service.ts", - "type": "file", - "name": "auth.service.ts", - "filePath": "src/services/auth.service.ts", - "summary": "Authentication service handling password hashing with bcrypt, JWT token generation/verification, and refresh token rotation.", - "tags": ["service", "auth", "security"], - "complexity": "complex" - }, - { - "id": "file:src/services/notification.service.ts", - "type": "file", - "name": "notification.service.ts", - "filePath": "src/services/notification.service.ts", - "summary": "Manages real-time notifications via WebSocket. Subscribes to domain events (task created, assigned, status changed) and broadcasts to relevant connected clients.", - "tags": ["service", "websocket", "events", "realtime"], - "complexity": "complex" - }, - { - "id": "class:src/models/Task.ts:Task", - "type": "class", - "name": "Task", - "filePath": "src/models/Task.ts", - "lineRange": [8, 45], - "summary": "Prisma model wrapper for tasks. Defines the schema fields (title, description, status, priority, dueDate, assigneeId, projectId) and provides static query helpers.", - "tags": ["model", "prisma", "database"], - "complexity": "moderate" - }, - { - "id": "class:src/models/User.ts:User", - "type": "class", - "name": "User", - "filePath": "src/models/User.ts", - "lineRange": [5, 38], - "summary": "Prisma model wrapper for users. Stores email, hashed password, display name, and role. Provides methods for credential verification and profile serialization.", - "tags": ["model", "prisma", "auth"], - "complexity": "moderate" - }, - { - "id": "file:src/db/prisma.ts", - "type": "file", - "name": "prisma.ts", - "filePath": "src/db/prisma.ts", - "summary": "Singleton Prisma client instance. Configures connection pooling, logging levels, and graceful shutdown hooks.", - "tags": ["database", "prisma", "connection"], - "complexity": "simple" - }, - { - "id": "file:src/middleware/auth.middleware.ts", - "type": "file", - "name": "auth.middleware.ts", - "filePath": "src/middleware/auth.middleware.ts", - "summary": "Express middleware that extracts and verifies JWT from the Authorization header. Attaches the decoded user payload to req.user for downstream handlers.", - "tags": ["middleware", "auth", "jwt"], - "complexity": "moderate" - }, - { - "id": "func:src/middleware/auth.middleware.ts:requireRole", - "type": "function", - "name": "requireRole", - "filePath": "src/middleware/auth.middleware.ts", - "lineRange": [28, 44], - "summary": "Higher-order middleware factory that checks if the authenticated user has one of the required roles. Returns 403 Forbidden if the role check fails.", - "tags": ["rbac", "authorization", "middleware"], - "complexity": "simple" - }, - { - "id": "file:src/utils/validate.ts", - "type": "file", - "name": "validate.ts", - "filePath": "src/utils/validate.ts", - "summary": "Shared Zod schemas and a validateBody middleware factory. Schemas cover task creation, user registration, and project settings validation.", - "tags": ["validation", "zod", "schemas"], - "complexity": "simple" - }, - { - "id": "file:src/utils/logger.ts", - "type": "file", - "name": "logger.ts", - "filePath": "src/utils/logger.ts", - "summary": "Structured logging utility built on pino. Provides log levels (debug, info, warn, error) and request-scoped child loggers with correlation IDs.", - "tags": ["logging", "pino", "observability"], - "complexity": "simple" - }, - { - "id": "file:src/config.ts", - "type": "file", - "name": "config.ts", - "filePath": "src/config.ts", - "summary": "Loads environment variables and exports typed configuration: port, database URL, JWT secret, token expiry, log level, and WebSocket settings.", - "tags": ["config", "env", "settings"], - "complexity": "simple" - }, - { - "id": "module:src/routes", - "type": "module", - "name": "routes", - "filePath": "src/routes", - "summary": "Route module aggregating all HTTP endpoint definitions. Each route file maps URL paths to controller logic with middleware chains.", - "tags": ["module", "routing", "api"], - "complexity": "simple" - }, - { - "id": "concept:authentication-flow", - "type": "concept", - "name": "Authentication Flow", - "summary": "The system uses JWT-based stateless authentication. Users log in with email/password, receive an access token (15 min) and refresh token (7 days). The auth middleware validates tokens on protected routes, and the refresh endpoint rotates tokens to maintain sessions.", - "tags": ["concept", "auth", "jwt", "security"], - "complexity": "complex" - }, - { - "id": "concept:task-lifecycle", - "type": "concept", - "name": "Task Lifecycle", - "summary": "Tasks follow a state machine: todo -> in_progress -> review -> done. Only valid forward transitions are allowed. Each transition triggers a notification event and records a timestamp. Tasks can also be archived after completion.", - "tags": ["concept", "workflow", "state-machine"], - "complexity": "moderate" - } - ], - "edges": [ - { - "source": "file:src/index.ts", - "target": "file:src/routes/task.routes.ts", - "type": "imports", - "direction": "forward", - "description": "Mounts task routes at /api/tasks", - "weight": 0.8 - }, - { - "source": "file:src/index.ts", - "target": "file:src/routes/auth.routes.ts", - "type": "imports", - "direction": "forward", - "description": "Mounts auth routes at /api/auth", - "weight": 0.8 - }, - { - "source": "file:src/index.ts", - "target": "file:src/routes/project.routes.ts", - "type": "imports", - "direction": "forward", - "description": "Mounts project routes at /api/projects", - "weight": 0.8 - }, - { - "source": "file:src/index.ts", - "target": "file:src/config.ts", - "type": "imports", - "direction": "forward", - "description": "Reads server port and startup configuration", - "weight": 0.6 - }, - { - "source": "file:src/index.ts", - "target": "file:src/middleware/auth.middleware.ts", - "type": "middleware", - "direction": "forward", - "description": "Applies JWT auth middleware globally to protected routes", - "weight": 0.7 - }, - { - "source": "module:src/routes", - "target": "file:src/routes/task.routes.ts", - "type": "contains", - "direction": "forward", - "weight": 1.0 - }, - { - "source": "module:src/routes", - "target": "file:src/routes/auth.routes.ts", - "type": "contains", - "direction": "forward", - "weight": 1.0 - }, - { - "source": "module:src/routes", - "target": "file:src/routes/project.routes.ts", - "type": "contains", - "direction": "forward", - "weight": 1.0 - }, - { - "source": "file:src/routes/task.routes.ts", - "target": "file:src/services/task.service.ts", - "type": "calls", - "direction": "forward", - "description": "Delegates task operations to the service layer", - "weight": 0.9 - }, - { - "source": "file:src/routes/task.routes.ts", - "target": "file:src/utils/validate.ts", - "type": "validates", - "direction": "forward", - "description": "Uses Zod schemas to validate incoming task payloads", - "weight": 0.7 - }, - { - "source": "file:src/routes/auth.routes.ts", - "target": "file:src/services/auth.service.ts", - "type": "calls", - "direction": "forward", - "description": "Delegates login, register, and token refresh to auth service", - "weight": 0.9 - }, - { - "source": "file:src/routes/project.routes.ts", - "target": "file:src/middleware/auth.middleware.ts", - "type": "depends_on", - "direction": "forward", - "description": "Requires authentication and role checking on all endpoints", - "weight": 0.8 - }, - { - "source": "file:src/services/task.service.ts", - "target": "func:src/services/task.service.ts:createTask", - "type": "contains", - "direction": "forward", - "weight": 1.0 - }, - { - "source": "file:src/services/task.service.ts", - "target": "func:src/services/task.service.ts:transitionStatus", - "type": "contains", - "direction": "forward", - "weight": 1.0 - }, - { - "source": "file:src/services/task.service.ts", - "target": "class:src/models/Task.ts:Task", - "type": "reads_from", - "direction": "forward", - "description": "Queries and mutates task records via the Task model", - "weight": 0.9 - }, - { - "source": "file:src/services/task.service.ts", - "target": "file:src/services/notification.service.ts", - "type": "publishes", - "direction": "forward", - "description": "Emits TASK_CREATED and STATUS_CHANGED events to the notification service", - "weight": 0.7 - }, - { - "source": "file:src/services/auth.service.ts", - "target": "class:src/models/User.ts:User", - "type": "reads_from", - "direction": "forward", - "description": "Looks up users for authentication and creates new user records", - "weight": 0.9 - }, - { - "source": "file:src/services/auth.service.ts", - "target": "file:src/config.ts", - "type": "configures", - "direction": "backward", - "description": "Reads JWT secret and token expiry from configuration", - "weight": 0.6 - }, - { - "source": "file:src/services/notification.service.ts", - "target": "file:src/utils/logger.ts", - "type": "depends_on", - "direction": "forward", - "description": "Logs WebSocket connection events and notification delivery", - "weight": 0.5 - }, - { - "source": "class:src/models/Task.ts:Task", - "target": "file:src/db/prisma.ts", - "type": "depends_on", - "direction": "forward", - "description": "Uses the shared Prisma client for all database queries", - "weight": 0.9 - }, - { - "source": "class:src/models/User.ts:User", - "target": "file:src/db/prisma.ts", - "type": "depends_on", - "direction": "forward", - "description": "Uses the shared Prisma client for user queries", - "weight": 0.9 - }, - { - "source": "file:src/middleware/auth.middleware.ts", - "target": "file:src/middleware/auth.middleware.ts", - "type": "contains", - "direction": "forward", - "weight": 1.0 - }, - { - "source": "file:src/middleware/auth.middleware.ts", - "target": "func:src/middleware/auth.middleware.ts:requireRole", - "type": "contains", - "direction": "forward", - "weight": 1.0 - }, - { - "source": "concept:authentication-flow", - "target": "file:src/services/auth.service.ts", - "type": "related", - "direction": "forward", - "description": "Auth service implements the core authentication flow", - "weight": 0.9 - }, - { - "source": "concept:authentication-flow", - "target": "file:src/middleware/auth.middleware.ts", - "type": "related", - "direction": "forward", - "description": "Auth middleware enforces the authentication flow on routes", - "weight": 0.8 - }, - { - "source": "concept:task-lifecycle", - "target": "func:src/services/task.service.ts:transitionStatus", - "type": "related", - "direction": "forward", - "description": "The transitionStatus function implements the task state machine", - "weight": 0.9 - }, - { - "source": "concept:task-lifecycle", - "target": "file:src/services/notification.service.ts", - "type": "related", - "direction": "forward", - "description": "Lifecycle transitions trigger real-time notifications", - "weight": 0.7 - }, - { - "source": "func:src/services/task.service.ts:createTask", - "target": "file:src/utils/validate.ts", - "type": "validates", - "direction": "forward", - "description": "Validates task data before persisting", - "weight": 0.6 - } - ], - "layers": [ - { - "id": "layer:api", - "name": "API Layer", - "description": "HTTP route handlers and request/response processing. The entry point for all client interactions with the system.", - "nodeIds": [ - "file:src/index.ts", - "file:src/routes/task.routes.ts", - "file:src/routes/auth.routes.ts", - "file:src/routes/project.routes.ts", - "module:src/routes" - ] - }, - { - "id": "layer:service", - "name": "Service Layer", - "description": "Core business logic and domain operations. Orchestrates data access, validation, event publishing, and enforces business rules.", - "nodeIds": [ - "file:src/services/task.service.ts", - "func:src/services/task.service.ts:createTask", - "func:src/services/task.service.ts:transitionStatus", - "file:src/services/auth.service.ts", - "file:src/services/notification.service.ts" - ] - }, - { - "id": "layer:data", - "name": "Data Layer", - "description": "Database models, Prisma client, and data access patterns. Provides the persistence foundation for all domain entities.", - "nodeIds": [ - "class:src/models/Task.ts:Task", - "class:src/models/User.ts:User", - "file:src/db/prisma.ts" - ] - }, - { - "id": "layer:middleware", - "name": "Middleware Layer", - "description": "Cross-cutting concerns applied to request pipelines: authentication, authorization, and request validation.", - "nodeIds": [ - "file:src/middleware/auth.middleware.ts", - "func:src/middleware/auth.middleware.ts:requireRole", - "file:src/utils/validate.ts" - ] - }, - { - "id": "layer:infrastructure", - "name": "Infrastructure Layer", - "description": "Configuration, logging, and shared utilities that support all other layers without containing business logic.", - "nodeIds": [ - "file:src/config.ts", - "file:src/utils/logger.ts", - "concept:authentication-flow", - "concept:task-lifecycle" - ] - } - ], - "tour": [ - { - "order": 1, - "title": "Where It All Begins", - "description": "The application starts in index.ts, which wires up Express middleware and mounts all the route handlers. Think of it as the front door of the API.", - "nodeIds": ["file:src/index.ts"] - }, - { - "order": 2, - "title": "Handling Requests", - "description": "Incoming HTTP requests hit the route files. Each route file defines endpoints for a domain area (tasks, auth, projects) and validates input before passing it along.", - "nodeIds": [ - "file:src/routes/task.routes.ts", - "file:src/routes/auth.routes.ts", - "file:src/routes/project.routes.ts" - ] - }, - { - "order": 3, - "title": "Security Gate", - "description": "Before most routes run, the auth middleware checks the JWT token. The requireRole function adds role-based access control on top of basic authentication.", - "nodeIds": [ - "file:src/middleware/auth.middleware.ts", - "func:src/middleware/auth.middleware.ts:requireRole" - ], - "languageLesson": "JWT (JSON Web Token) is a compact token format that encodes user identity and permissions. It lets the server verify who you are without storing session data." - }, - { - "order": 4, - "title": "Business Logic", - "description": "Services contain the real brains of the application. TaskService manages task creation and status transitions, while AuthService handles password hashing and token management.", - "nodeIds": [ - "file:src/services/task.service.ts", - "func:src/services/task.service.ts:createTask", - "func:src/services/task.service.ts:transitionStatus", - "file:src/services/auth.service.ts" - ] - }, - { - "order": 5, - "title": "Data Persistence", - "description": "The Task and User models wrap Prisma queries. They talk to the database through a shared Prisma client configured in prisma.ts.", - "nodeIds": [ - "class:src/models/Task.ts:Task", - "class:src/models/User.ts:User", - "file:src/db/prisma.ts" - ], - "languageLesson": "Prisma is an ORM (Object-Relational Mapper) that lets you write database queries in TypeScript instead of raw SQL. It auto-generates types from your schema." - }, - { - "order": 6, - "title": "Real-Time Updates", - "description": "When tasks change state, the notification service broadcasts updates over WebSocket so connected clients see changes immediately without polling.", - "nodeIds": ["file:src/services/notification.service.ts"] - } - ] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c903a3d..c43a845 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,23 @@ importers: specifier: ^3.1.0 version: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.31.1) - packages/core: + understand-anything-plugin: + dependencies: + '@understand-anything/core': + specifier: workspace:* + version: link:packages/core + devDependencies: + '@types/node': + specifier: ^22.0.0 + version: 22.19.15 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + vitest: + specifier: ^3.1.0 + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.31.1) + + understand-anything-plugin/packages/core: dependencies: fuse.js: specifier: ^7.1.0 @@ -43,7 +59,7 @@ importers: specifier: ^3.1.0 version: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.31.1) - packages/dashboard: + understand-anything-plugin/packages/dashboard: dependencies: '@anthropic-ai/sdk': specifier: ^0.78.0 @@ -95,22 +111,6 @@ importers: specifier: ^6.0.0 version: 6.4.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.31.1) - packages/skill: - dependencies: - '@understand-anything/core': - specifier: workspace:* - version: link:../core - devDependencies: - '@types/node': - specifier: ^22.0.0 - version: 22.19.15 - typescript: - specifier: ^5.7.0 - version: 5.9.3 - vitest: - specifier: ^3.1.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.31.1) - packages: '@anthropic-ai/sdk@0.78.0': @@ -2268,6 +2268,14 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.31.1))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.31.1) + '@vitest/mocker@3.2.4(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.31.1))': dependencies: '@vitest/spy': 3.2.4 @@ -3213,7 +3221,7 @@ snapshots: dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.31.1)) + '@vitest/mocker': 3.2.4(vite@7.3.1(@types/node@22.19.15)(jiti@2.6.1)(lightningcss@1.31.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 18ec407..445d43d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - - 'packages/*' + - 'understand-anything-plugin/packages/*' + - 'understand-anything-plugin' diff --git a/packages/skill/.claude-plugin/plugin.json b/understand-anything-plugin/.claude-plugin/plugin.json similarity index 100% rename from packages/skill/.claude-plugin/plugin.json rename to understand-anything-plugin/.claude-plugin/plugin.json diff --git a/packages/skill/agents/architecture-analyzer.md b/understand-anything-plugin/agents/architecture-analyzer.md similarity index 100% rename from packages/skill/agents/architecture-analyzer.md rename to understand-anything-plugin/agents/architecture-analyzer.md diff --git a/packages/skill/agents/file-analyzer.md b/understand-anything-plugin/agents/file-analyzer.md similarity index 100% rename from packages/skill/agents/file-analyzer.md rename to understand-anything-plugin/agents/file-analyzer.md diff --git a/packages/skill/agents/graph-reviewer.md b/understand-anything-plugin/agents/graph-reviewer.md similarity index 100% rename from packages/skill/agents/graph-reviewer.md rename to understand-anything-plugin/agents/graph-reviewer.md diff --git a/packages/skill/agents/project-scanner.md b/understand-anything-plugin/agents/project-scanner.md similarity index 100% rename from packages/skill/agents/project-scanner.md rename to understand-anything-plugin/agents/project-scanner.md diff --git a/packages/skill/agents/tour-builder.md b/understand-anything-plugin/agents/tour-builder.md similarity index 100% rename from packages/skill/agents/tour-builder.md rename to understand-anything-plugin/agents/tour-builder.md diff --git a/packages/skill/package.json b/understand-anything-plugin/package.json similarity index 100% rename from packages/skill/package.json rename to understand-anything-plugin/package.json diff --git a/packages/core/package.json b/understand-anything-plugin/packages/core/package.json similarity index 100% rename from packages/core/package.json rename to understand-anything-plugin/packages/core/package.json diff --git a/packages/core/src/__tests__/embedding-search.test.ts b/understand-anything-plugin/packages/core/src/__tests__/embedding-search.test.ts similarity index 100% rename from packages/core/src/__tests__/embedding-search.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/embedding-search.test.ts diff --git a/packages/core/src/__tests__/language-lesson.test.ts b/understand-anything-plugin/packages/core/src/__tests__/language-lesson.test.ts similarity index 100% rename from packages/core/src/__tests__/language-lesson.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/language-lesson.test.ts diff --git a/packages/core/src/__tests__/layer-detector.test.ts b/understand-anything-plugin/packages/core/src/__tests__/layer-detector.test.ts similarity index 100% rename from packages/core/src/__tests__/layer-detector.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/layer-detector.test.ts diff --git a/packages/core/src/__tests__/plugin-discovery.test.ts b/understand-anything-plugin/packages/core/src/__tests__/plugin-discovery.test.ts similarity index 100% rename from packages/core/src/__tests__/plugin-discovery.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/plugin-discovery.test.ts diff --git a/packages/core/src/__tests__/plugin-registry.test.ts b/understand-anything-plugin/packages/core/src/__tests__/plugin-registry.test.ts similarity index 100% rename from packages/core/src/__tests__/plugin-registry.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/plugin-registry.test.ts diff --git a/packages/core/src/__tests__/schema.test.ts b/understand-anything-plugin/packages/core/src/__tests__/schema.test.ts similarity index 100% rename from packages/core/src/__tests__/schema.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/schema.test.ts diff --git a/packages/core/src/__tests__/search.test.ts b/understand-anything-plugin/packages/core/src/__tests__/search.test.ts similarity index 100% rename from packages/core/src/__tests__/search.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/search.test.ts diff --git a/packages/core/src/__tests__/staleness.test.ts b/understand-anything-plugin/packages/core/src/__tests__/staleness.test.ts similarity index 100% rename from packages/core/src/__tests__/staleness.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/staleness.test.ts diff --git a/packages/core/src/__tests__/tour-generator.test.ts b/understand-anything-plugin/packages/core/src/__tests__/tour-generator.test.ts similarity index 100% rename from packages/core/src/__tests__/tour-generator.test.ts rename to understand-anything-plugin/packages/core/src/__tests__/tour-generator.test.ts diff --git a/packages/core/src/analyzer/graph-builder.test.ts b/understand-anything-plugin/packages/core/src/analyzer/graph-builder.test.ts similarity index 100% rename from packages/core/src/analyzer/graph-builder.test.ts rename to understand-anything-plugin/packages/core/src/analyzer/graph-builder.test.ts diff --git a/packages/core/src/analyzer/graph-builder.ts b/understand-anything-plugin/packages/core/src/analyzer/graph-builder.ts similarity index 100% rename from packages/core/src/analyzer/graph-builder.ts rename to understand-anything-plugin/packages/core/src/analyzer/graph-builder.ts diff --git a/packages/core/src/analyzer/language-lesson.ts b/understand-anything-plugin/packages/core/src/analyzer/language-lesson.ts similarity index 100% rename from packages/core/src/analyzer/language-lesson.ts rename to understand-anything-plugin/packages/core/src/analyzer/language-lesson.ts diff --git a/packages/core/src/analyzer/layer-detector.ts b/understand-anything-plugin/packages/core/src/analyzer/layer-detector.ts similarity index 100% rename from packages/core/src/analyzer/layer-detector.ts rename to understand-anything-plugin/packages/core/src/analyzer/layer-detector.ts diff --git a/packages/core/src/analyzer/llm-analyzer.test.ts b/understand-anything-plugin/packages/core/src/analyzer/llm-analyzer.test.ts similarity index 100% rename from packages/core/src/analyzer/llm-analyzer.test.ts rename to understand-anything-plugin/packages/core/src/analyzer/llm-analyzer.test.ts diff --git a/packages/core/src/analyzer/llm-analyzer.ts b/understand-anything-plugin/packages/core/src/analyzer/llm-analyzer.ts similarity index 100% rename from packages/core/src/analyzer/llm-analyzer.ts rename to understand-anything-plugin/packages/core/src/analyzer/llm-analyzer.ts diff --git a/packages/core/src/analyzer/tour-generator.ts b/understand-anything-plugin/packages/core/src/analyzer/tour-generator.ts similarity index 100% rename from packages/core/src/analyzer/tour-generator.ts rename to understand-anything-plugin/packages/core/src/analyzer/tour-generator.ts diff --git a/packages/core/src/embedding-search.ts b/understand-anything-plugin/packages/core/src/embedding-search.ts similarity index 100% rename from packages/core/src/embedding-search.ts rename to understand-anything-plugin/packages/core/src/embedding-search.ts diff --git a/packages/core/src/index.ts b/understand-anything-plugin/packages/core/src/index.ts similarity index 100% rename from packages/core/src/index.ts rename to understand-anything-plugin/packages/core/src/index.ts diff --git a/packages/core/src/persistence/index.ts b/understand-anything-plugin/packages/core/src/persistence/index.ts similarity index 100% rename from packages/core/src/persistence/index.ts rename to understand-anything-plugin/packages/core/src/persistence/index.ts diff --git a/packages/core/src/persistence/persistence.test.ts b/understand-anything-plugin/packages/core/src/persistence/persistence.test.ts similarity index 100% rename from packages/core/src/persistence/persistence.test.ts rename to understand-anything-plugin/packages/core/src/persistence/persistence.test.ts diff --git a/packages/core/src/plugins/discovery.ts b/understand-anything-plugin/packages/core/src/plugins/discovery.ts similarity index 100% rename from packages/core/src/plugins/discovery.ts rename to understand-anything-plugin/packages/core/src/plugins/discovery.ts diff --git a/packages/core/src/plugins/registry.ts b/understand-anything-plugin/packages/core/src/plugins/registry.ts similarity index 100% rename from packages/core/src/plugins/registry.ts rename to understand-anything-plugin/packages/core/src/plugins/registry.ts diff --git a/packages/core/src/plugins/tree-sitter-plugin.test.ts b/understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.test.ts similarity index 100% rename from packages/core/src/plugins/tree-sitter-plugin.test.ts rename to understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.test.ts diff --git a/packages/core/src/plugins/tree-sitter-plugin.ts b/understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.ts similarity index 100% rename from packages/core/src/plugins/tree-sitter-plugin.ts rename to understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.ts diff --git a/packages/core/src/schema.ts b/understand-anything-plugin/packages/core/src/schema.ts similarity index 100% rename from packages/core/src/schema.ts rename to understand-anything-plugin/packages/core/src/schema.ts diff --git a/packages/core/src/search.ts b/understand-anything-plugin/packages/core/src/search.ts similarity index 100% rename from packages/core/src/search.ts rename to understand-anything-plugin/packages/core/src/search.ts diff --git a/packages/core/src/staleness.ts b/understand-anything-plugin/packages/core/src/staleness.ts similarity index 100% rename from packages/core/src/staleness.ts rename to understand-anything-plugin/packages/core/src/staleness.ts diff --git a/packages/core/src/types.test.ts b/understand-anything-plugin/packages/core/src/types.test.ts similarity index 100% rename from packages/core/src/types.test.ts rename to understand-anything-plugin/packages/core/src/types.test.ts diff --git a/packages/core/src/types.ts b/understand-anything-plugin/packages/core/src/types.ts similarity index 100% rename from packages/core/src/types.ts rename to understand-anything-plugin/packages/core/src/types.ts diff --git a/packages/skill/tsconfig.json b/understand-anything-plugin/packages/core/tsconfig.json similarity index 71% rename from packages/skill/tsconfig.json rename to understand-anything-plugin/packages/core/tsconfig.json index a086b14..2f355cf 100644 --- a/packages/skill/tsconfig.json +++ b/understand-anything-plugin/packages/core/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "../../../tsconfig.json", "compilerOptions": { "outDir": "dist", "rootDir": "src" diff --git a/packages/dashboard/index.html b/understand-anything-plugin/packages/dashboard/index.html similarity index 100% rename from packages/dashboard/index.html rename to understand-anything-plugin/packages/dashboard/index.html diff --git a/packages/dashboard/package.json b/understand-anything-plugin/packages/dashboard/package.json similarity index 100% rename from packages/dashboard/package.json rename to understand-anything-plugin/packages/dashboard/package.json diff --git a/understand-anything-plugin/packages/dashboard/public/knowledge-graph.json b/understand-anything-plugin/packages/dashboard/public/knowledge-graph.json new file mode 100644 index 0000000..84cec42 --- /dev/null +++ b/understand-anything-plugin/packages/dashboard/public/knowledge-graph.json @@ -0,0 +1,3088 @@ +{ + "version": "1.0.0", + "project": { + "name": "understand-anything", + "languages": [ + "typescript", + "css" + ], + "frameworks": [ + "React", + "Vite", + "TailwindCSS", + "Zustand", + "React Flow", + "Monaco Editor", + "Vitest", + "Zod", + "Fuse.js", + "Dagre", + "tree-sitter", + "Anthropic SDK" + ], + "description": "An open-source tool combining LLM intelligence with static analysis to produce interactive dashboards for understanding codebases.", + "analyzedAt": "2026-03-14T16:15:02.617Z", + "gitCommitHash": "58cfb20ac8f3f98cd7dede428d147dbe9cdc94b2" + }, + "nodes": [ + { + "id": "file:packages/core/src/types.ts", + "type": "file", + "name": "types.ts", + "filePath": "packages/core/src/types.ts", + "summary": "Defines all core TypeScript interfaces and types for the knowledge graph system, including GraphNode, GraphEdge, KnowledgeGraph, Layer, TourStep, ProjectMeta, AnalysisMeta, and the AnalyzerPlugin interface contract.", + "tags": [ + "data-model", + "types", + "interfaces", + "knowledge-graph", + "plugin-api" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/schema.ts", + "type": "file", + "name": "schema.ts", + "filePath": "packages/core/src/schema.ts", + "summary": "Provides Zod runtime schema validation for all KnowledgeGraph data structures, mirroring the TypeScript type definitions in types.ts and exposing a validateGraph function.", + "tags": [ + "validation", + "zod", + "schema", + "runtime-safety", + "knowledge-graph" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/index.ts", + "type": "file", + "name": "index.ts", + "filePath": "packages/core/src/index.ts", + "summary": "Barrel entry point for the core package that re-exports all public APIs including types, persistence, schema validation, tree-sitter plugin, graph builder, LLM analyzer, search engines, staleness detection, layer detection, tour generation, language lessons, plugin registry, and plugin discovery.", + "tags": [ + "entry-point", + "barrel", + "exports", + "api-surface" + ], + "complexity": "simple" + }, + { + "id": "file:packages/core/src/search.ts", + "type": "file", + "name": "search.ts", + "filePath": "packages/core/src/search.ts", + "summary": "Implements fuzzy search over graph nodes using Fuse.js with weighted fields, extended OR-query tokenization, and optional type filtering.", + "tags": [ + "search", + "fuzzy-search", + "fuse.js", + "utility" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/staleness.ts", + "type": "file", + "name": "staleness.ts", + "filePath": "packages/core/src/staleness.ts", + "summary": "Detects whether the persisted knowledge graph is stale relative to the current git HEAD by diffing commit hashes, and provides incremental graph merging.", + "tags": [ + "staleness", + "git", + "incremental-update", + "graph-merge" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/embedding-search.ts", + "type": "file", + "name": "embedding-search.ts", + "filePath": "packages/core/src/embedding-search.ts", + "summary": "Implements vector-embedding-based semantic search over graph nodes using cosine similarity, with score inversion to match Fuse.js convention.", + "tags": [ + "semantic-search", + "embeddings", + "cosine-similarity", + "utility" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/schema.ts:validateGraph", + "type": "function", + "name": "validateGraph", + "filePath": "packages/core/src/schema.ts", + "lineRange": [ + 72, + 85 + ], + "summary": "Validates an unknown value against the KnowledgeGraphSchema using Zod's safeParse, returning a structured ValidationResult.", + "tags": [ + "validation", + "zod", + "error-handling" + ], + "complexity": "simple" + }, + { + "id": "class:packages/core/src/search.ts:SearchEngine", + "type": "class", + "name": "SearchEngine", + "filePath": "packages/core/src/search.ts", + "lineRange": [ + 27, + 65 + ], + "summary": "Wraps Fuse.js to provide fuzzy search over GraphNode arrays with weighted field scoring, OR-tokenized queries, type filtering, and live index rebuilding.", + "tags": [ + "fuzzy-search", + "fuse.js", + "search-engine", + "utility" + ], + "complexity": "moderate" + }, + { + "id": "class:packages/core/src/embedding-search.ts:SemanticSearchEngine", + "type": "class", + "name": "SemanticSearchEngine", + "filePath": "packages/core/src/embedding-search.ts", + "lineRange": [ + 37, + 83 + ], + "summary": "Vector search engine using pre-computed embeddings and cosine similarity with optional type and threshold filters.", + "tags": [ + "semantic-search", + "embeddings", + "vector-search" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/embedding-search.ts:cosineSimilarity", + "type": "function", + "name": "cosineSimilarity", + "filePath": "packages/core/src/embedding-search.ts", + "lineRange": [ + 14, + 30 + ], + "summary": "Computes the cosine similarity between two numeric vectors in a single pass.", + "tags": [ + "math", + "cosine-similarity", + "utility" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/staleness.ts:getChangedFiles", + "type": "function", + "name": "getChangedFiles", + "filePath": "packages/core/src/staleness.ts", + "lineRange": [ + 13, + 29 + ], + "summary": "Shells out to git diff to retrieve the list of files changed between a given commit hash and HEAD.", + "tags": [ + "git", + "file-diff", + "utility" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/staleness.ts:isStale", + "type": "function", + "name": "isStale", + "filePath": "packages/core/src/staleness.ts", + "lineRange": [ + 34, + 43 + ], + "summary": "Determines if the knowledge graph is stale by checking whether any files changed since the last analyzed commit hash.", + "tags": [ + "staleness", + "git", + "utility" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/staleness.ts:mergeGraphUpdate", + "type": "function", + "name": "mergeGraphUpdate", + "filePath": "packages/core/src/staleness.ts", + "lineRange": [ + 54, + 90 + ], + "summary": "Incrementally updates an existing KnowledgeGraph by removing nodes and edges associated with changed files and appending newly analyzed nodes.", + "tags": [ + "graph-merge", + "incremental-update", + "staleness" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/analyzer/graph-builder.ts", + "type": "file", + "name": "graph-builder.ts", + "filePath": "packages/core/src/analyzer/graph-builder.ts", + "summary": "Defines the GraphBuilder class that incrementally accumulates file, function, and class nodes plus edges before assembling a final KnowledgeGraph.", + "tags": [ + "graph", + "builder", + "static-analysis", + "data-model" + ], + "complexity": "moderate" + }, + { + "id": "class:packages/core/src/analyzer/graph-builder.ts:GraphBuilder", + "type": "class", + "name": "GraphBuilder", + "filePath": "packages/core/src/analyzer/graph-builder.ts", + "lineRange": [ + 63, + 207 + ], + "summary": "Stateful builder that collects nodes and edges incrementally via addFile, addFileWithAnalysis, addImportEdge, addCallEdge, then emits a KnowledgeGraph via build().", + "tags": [ + "builder-pattern", + "graph", + "accumulator" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/graph-builder.ts:detectLanguage", + "type": "function", + "name": "detectLanguage", + "filePath": "packages/core/src/analyzer/graph-builder.ts", + "lineRange": [ + 56, + 61 + ], + "summary": "Derives a language identifier string from a file path by matching its extension.", + "tags": [ + "utility", + "language-detection" + ], + "complexity": "simple" + }, + { + "id": "file:packages/core/src/analyzer/llm-analyzer.ts", + "type": "file", + "name": "llm-analyzer.ts", + "filePath": "packages/core/src/analyzer/llm-analyzer.ts", + "summary": "Provides prompt-builder functions and response-parser functions for LLM-based file analysis and project-level summary.", + "tags": [ + "llm", + "prompt-template", + "parser", + "analysis" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/llm-analyzer.ts:buildFileAnalysisPrompt", + "type": "function", + "name": "buildFileAnalysisPrompt", + "filePath": "packages/core/src/analyzer/llm-analyzer.ts", + "lineRange": [ + 19, + 43 + ], + "summary": "Constructs an LLM prompt for analyzing a single source file.", + "tags": [ + "prompt-builder", + "llm", + "file-analysis" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/analyzer/llm-analyzer.ts:buildProjectSummaryPrompt", + "type": "function", + "name": "buildProjectSummaryPrompt", + "filePath": "packages/core/src/analyzer/llm-analyzer.ts", + "lineRange": [ + 48, + 76 + ], + "summary": "Constructs an LLM prompt for generating a project-level summary.", + "tags": [ + "prompt-builder", + "llm", + "project-summary" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/analyzer/llm-analyzer.ts:parseFileAnalysisResponse", + "type": "function", + "name": "parseFileAnalysisResponse", + "filePath": "packages/core/src/analyzer/llm-analyzer.ts", + "lineRange": [ + 102, + 143 + ], + "summary": "Parses an LLM JSON response for file analysis into a typed LLMFileAnalysis object.", + "tags": [ + "parser", + "llm", + "validation" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/llm-analyzer.ts:parseProjectSummaryResponse", + "type": "function", + "name": "parseProjectSummaryResponse", + "filePath": "packages/core/src/analyzer/llm-analyzer.ts", + "lineRange": [ + 148, + 186 + ], + "summary": "Parses an LLM JSON response for project summary.", + "tags": [ + "parser", + "llm", + "validation" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/analyzer/layer-detector.ts", + "type": "file", + "name": "layer-detector.ts", + "filePath": "packages/core/src/analyzer/layer-detector.ts", + "summary": "Implements heuristic and LLM-driven architectural layer detection.", + "tags": [ + "layer-detection", + "architecture", + "llm", + "heuristic" + ], + "complexity": "complex" + }, + { + "id": "func:packages/core/src/analyzer/layer-detector.ts:detectLayers", + "type": "function", + "name": "detectLayers", + "filePath": "packages/core/src/analyzer/layer-detector.ts", + "lineRange": [ + 95, + 134 + ], + "summary": "Heuristically assigns file nodes to named architectural layers by matching directory paths.", + "tags": [ + "heuristic", + "layer-detection", + "graph" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/layer-detector.ts:buildLayerDetectionPrompt", + "type": "function", + "name": "buildLayerDetectionPrompt", + "filePath": "packages/core/src/analyzer/layer-detector.ts", + "lineRange": [ + 140, + 160 + ], + "summary": "Builds an LLM prompt for identifying architectural layers.", + "tags": [ + "prompt-builder", + "llm", + "layer-detection" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/analyzer/layer-detector.ts:parseLayerDetectionResponse", + "type": "function", + "name": "parseLayerDetectionResponse", + "filePath": "packages/core/src/analyzer/layer-detector.ts", + "lineRange": [ + 167, + 210 + ], + "summary": "Parses and validates an LLM JSON response for layer detection.", + "tags": [ + "parser", + "llm", + "validation" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/layer-detector.ts:applyLLMLayers", + "type": "function", + "name": "applyLLMLayers", + "filePath": "packages/core/src/analyzer/layer-detector.ts", + "lineRange": [ + 217, + 274 + ], + "summary": "Applies LLM-provided layer definitions to a KnowledgeGraph by prefix-matching file paths.", + "tags": [ + "layer-assignment", + "llm", + "graph" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/analyzer/language-lesson.ts", + "type": "file", + "name": "language-lesson.ts", + "filePath": "packages/core/src/analyzer/language-lesson.ts", + "summary": "Detects language-specific programming concepts and generates LLM prompts for beginner-friendly language lessons.", + "tags": [ + "language-lesson", + "llm", + "prompt-template", + "education" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/language-lesson.ts:detectLanguageConcepts", + "type": "function", + "name": "detectLanguageConcepts", + "filePath": "packages/core/src/analyzer/language-lesson.ts", + "lineRange": [ + 42, + 64 + ], + "summary": "Scans a graph node for keywords matching 12 pre-defined concept patterns.", + "tags": [ + "concept-detection", + "keyword-matching", + "graph" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/analyzer/language-lesson.ts:buildLanguageLessonPrompt", + "type": "function", + "name": "buildLanguageLessonPrompt", + "filePath": "packages/core/src/analyzer/language-lesson.ts", + "lineRange": [ + 75, + 119 + ], + "summary": "Constructs an LLM prompt for generating a language lesson for a graph node.", + "tags": [ + "prompt-builder", + "llm", + "education" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/language-lesson.ts:parseLanguageLessonResponse", + "type": "function", + "name": "parseLanguageLessonResponse", + "filePath": "packages/core/src/analyzer/language-lesson.ts", + "lineRange": [ + 142, + 174 + ], + "summary": "Parses an LLM JSON response for a language lesson.", + "tags": [ + "parser", + "llm", + "education" + ], + "complexity": "simple" + }, + { + "id": "file:packages/core/src/analyzer/tour-generator.ts", + "type": "file", + "name": "tour-generator.ts", + "filePath": "packages/core/src/analyzer/tour-generator.ts", + "summary": "Generates guided codebase tours via LLM prompts and heuristically using Kahn's topological sort algorithm.", + "tags": [ + "tour-generation", + "topological-sort", + "llm", + "graph", + "education" + ], + "complexity": "complex" + }, + { + "id": "func:packages/core/src/analyzer/tour-generator.ts:buildTourGenerationPrompt", + "type": "function", + "name": "buildTourGenerationPrompt", + "filePath": "packages/core/src/analyzer/tour-generator.ts", + "lineRange": [ + 7, + 62 + ], + "summary": "Builds an LLM prompt for generating a guided tour with ordered steps.", + "tags": [ + "prompt-builder", + "llm", + "tour" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/analyzer/tour-generator.ts:parseTourGenerationResponse", + "type": "function", + "name": "parseTourGenerationResponse", + "filePath": "packages/core/src/analyzer/tour-generator.ts", + "lineRange": [ + 70, + 120 + ], + "summary": "Parses an LLM JSON response for tour generation.", + "tags": [ + "parser", + "llm", + "tour" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/analyzer/tour-generator.ts:generateHeuristicTour", + "type": "function", + "name": "generateHeuristicTour", + "filePath": "packages/core/src/analyzer/tour-generator.ts", + "lineRange": [ + 135, + 293 + ], + "summary": "Generates a guided tour using Kahn's topological sort on the graph, grouping by architectural layer.", + "tags": [ + "topological-sort", + "heuristic", + "tour", + "graph" + ], + "complexity": "complex" + }, + { + "id": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "type": "file", + "name": "tree-sitter-plugin.ts", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "summary": "Implements the TreeSitterPlugin class, a full static-analysis plugin for TypeScript and JavaScript using web-tree-sitter WASM.", + "tags": [ + "plugin", + "static-analysis", + "tree-sitter", + "ast", + "parser" + ], + "complexity": "complex" + }, + { + "id": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "type": "class", + "name": "TreeSitterPlugin", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "lineRange": [ + 158, + 652 + ], + "summary": "Core analyzer plugin implementing AnalyzerPlugin interface; initializes WASM grammars and exposes analyzeFile, resolveImports, and extractCallGraph.", + "tags": [ + "plugin", + "analyzer", + "class", + "tree-sitter", + "implements" + ], + "complexity": "complex" + }, + { + "id": "func:packages/core/src/plugins/tree-sitter-plugin.ts:languageKeyFromPath", + "type": "function", + "name": "languageKeyFromPath", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "lineRange": [ + 17, + 32 + ], + "summary": "Maps a file path's extension to a tree-sitter language key string.", + "tags": [ + "utility", + "language-detection" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/plugins/tree-sitter-plugin.ts:traverse", + "type": "function", + "name": "traverse", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "lineRange": [ + 37, + 46 + ], + "summary": "Recursively traverses an AST node tree, invoking a visitor callback on every node.", + "tags": [ + "utility", + "ast", + "traversal" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/plugins/tree-sitter-plugin.ts:getStringValue", + "type": "function", + "name": "getStringValue", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "lineRange": [ + 51, + 61 + ], + "summary": "Extracts the unquoted string content from a tree-sitter string literal AST node.", + "tags": [ + "utility", + "ast", + "extraction" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractParams", + "type": "function", + "name": "extractParams", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "lineRange": [ + 66, + 105 + ], + "summary": "Extracts parameter name strings from a formal_parameters AST node.", + "tags": [ + "utility", + "ast", + "extraction", + "parameters" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractReturnType", + "type": "function", + "name": "extractReturnType", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "lineRange": [ + 110, + 119 + ], + "summary": "Extracts the return type annotation string from a function-like AST node.", + "tags": [ + "utility", + "ast", + "extraction", + "types" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractImportSpecifiers", + "type": "function", + "name": "extractImportSpecifiers", + "filePath": "packages/core/src/plugins/tree-sitter-plugin.ts", + "lineRange": [ + 124, + 156 + ], + "summary": "Extracts import specifier names from an import_clause AST node.", + "tags": [ + "utility", + "ast", + "extraction", + "imports" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/plugins/registry.ts", + "type": "file", + "name": "registry.ts", + "filePath": "packages/core/src/plugins/registry.ts", + "summary": "Defines the PluginRegistry class that maps language identifiers to registered AnalyzerPlugin instances.", + "tags": [ + "registry", + "plugin", + "dispatcher", + "language-map" + ], + "complexity": "moderate" + }, + { + "id": "class:packages/core/src/plugins/registry.ts:PluginRegistry", + "type": "class", + "name": "PluginRegistry", + "filePath": "packages/core/src/plugins/registry.ts", + "lineRange": [ + 25, + 79 + ], + "summary": "Registry managing AnalyzerPlugin instances, dispatching analysis calls by file extension or language.", + "tags": [ + "registry", + "class", + "plugin-management" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/core/src/plugins/discovery.ts", + "type": "file", + "name": "discovery.ts", + "filePath": "packages/core/src/plugins/discovery.ts", + "summary": "Defines plugin configuration types and utility functions to parse and serialize plugin configuration JSON.", + "tags": [ + "plugin", + "configuration", + "discovery", + "serialization" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/plugins/discovery.ts:parsePluginConfig", + "type": "function", + "name": "parsePluginConfig", + "filePath": "packages/core/src/plugins/discovery.ts", + "lineRange": [ + 26, + 57 + ], + "summary": "Parses a JSON string into a validated PluginConfig object with fallback.", + "tags": [ + "configuration", + "parsing", + "validation" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/plugins/discovery.ts:serializePluginConfig", + "type": "function", + "name": "serializePluginConfig", + "filePath": "packages/core/src/plugins/discovery.ts", + "lineRange": [ + 62, + 64 + ], + "summary": "Serializes a PluginConfig object to pretty-printed JSON.", + "tags": [ + "configuration", + "serialization" + ], + "complexity": "simple" + }, + { + "id": "file:packages/core/src/persistence/index.ts", + "type": "file", + "name": "persistence/index.ts", + "filePath": "packages/core/src/persistence/index.ts", + "summary": "Provides the persistence layer for saving and loading KnowledgeGraph and AnalysisMeta JSON files.", + "tags": [ + "persistence", + "file-io", + "knowledge-graph", + "validation" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/persistence/index.ts:saveGraph", + "type": "function", + "name": "saveGraph", + "filePath": "packages/core/src/persistence/index.ts", + "lineRange": [ + 18, + 21 + ], + "summary": "Writes a KnowledgeGraph as JSON to .understand-anything/knowledge-graph.json.", + "tags": [ + "persistence", + "write", + "knowledge-graph" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/persistence/index.ts:loadGraph", + "type": "function", + "name": "loadGraph", + "filePath": "packages/core/src/persistence/index.ts", + "lineRange": [ + 23, + 43 + ], + "summary": "Reads and parses knowledge-graph.json with optional Zod validation.", + "tags": [ + "persistence", + "read", + "knowledge-graph", + "validation" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/core/src/persistence/index.ts:saveMeta", + "type": "function", + "name": "saveMeta", + "filePath": "packages/core/src/persistence/index.ts", + "lineRange": [ + 45, + 48 + ], + "summary": "Writes AnalysisMeta to .understand-anything/meta.json.", + "tags": [ + "persistence", + "write", + "metadata" + ], + "complexity": "simple" + }, + { + "id": "func:packages/core/src/persistence/index.ts:loadMeta", + "type": "function", + "name": "loadMeta", + "filePath": "packages/core/src/persistence/index.ts", + "lineRange": [ + 50, + 54 + ], + "summary": "Reads and parses meta.json, returning null if not found.", + "tags": [ + "persistence", + "read", + "metadata" + ], + "complexity": "simple" + }, + { + "id": "file:packages/dashboard/src/App.tsx", + "type": "file", + "name": "App.tsx", + "filePath": "packages/dashboard/src/App.tsx", + "summary": "Root React component orchestrating the dashboard layout with persona-adaptive panel arrangements.", + "tags": [ + "entry-point", + "layout", + "react", + "persona-adaptive", + "dashboard" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/dashboard/src/App.tsx:App", + "type": "function", + "name": "App", + "filePath": "packages/dashboard/src/App.tsx", + "lineRange": [ + 13, + 167 + ], + "summary": "Main app component that fetches the knowledge graph on mount and renders a persona-adaptive multi-panel layout.", + "tags": [ + "react-component", + "layout", + "persona-adaptive" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/dashboard/src/main.tsx", + "type": "file", + "name": "main.tsx", + "filePath": "packages/dashboard/src/main.tsx", + "summary": "Application entry point that mounts the React root into the DOM under StrictMode.", + "tags": [ + "entry-point", + "bootstrap", + "react" + ], + "complexity": "simple" + }, + { + "id": "file:packages/dashboard/src/store.ts", + "type": "file", + "name": "store.ts", + "filePath": "packages/dashboard/src/store.ts", + "summary": "Zustand store defining complete dashboard state including graph data, search, chat messages, node explanations, persona selection, and tour management.", + "tags": [ + "state-management", + "zustand", + "chat", + "search", + "tour" + ], + "complexity": "complex" + }, + { + "id": "func:packages/dashboard/src/store.ts:buildSystemPrompt", + "type": "function", + "name": "buildSystemPrompt", + "filePath": "packages/dashboard/src/store.ts", + "lineRange": [ + 59, + 128 + ], + "summary": "Constructs a multi-section system prompt for the Claude API with full graph context.", + "tags": [ + "llm", + "prompt-engineering", + "context-builder" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/dashboard/src/store.ts:getSortedTour", + "type": "function", + "name": "getSortedTour", + "filePath": "packages/dashboard/src/store.ts", + "lineRange": [ + 130, + 132 + ], + "summary": "Returns tour steps sorted by order for sequential navigation.", + "tags": [ + "utility", + "tour" + ], + "complexity": "simple" + }, + { + "id": "func:packages/dashboard/src/store.ts:useDashboardStore", + "type": "function", + "name": "useDashboardStore", + "filePath": "packages/dashboard/src/store.ts", + "lineRange": [ + 134, + 378 + ], + "summary": "Zustand store hook exposing all dashboard state and actions: graph loading, node selection, search, chat, explanation, layer toggling, persona switching, and tour navigation.", + "tags": [ + "state-management", + "zustand", + "hook", + "api-handler" + ], + "complexity": "complex" + }, + { + "id": "file:packages/dashboard/src/utils/layout.ts", + "type": "file", + "name": "layout.ts", + "filePath": "packages/dashboard/src/utils/layout.ts", + "summary": "Utility applying Dagre hierarchical graph layout to React Flow nodes and edges.", + "tags": [ + "utility", + "layout", + "dagre", + "graph" + ], + "complexity": "simple" + }, + { + "id": "func:packages/dashboard/src/utils/layout.ts:applyDagreLayout", + "type": "function", + "name": "applyDagreLayout", + "filePath": "packages/dashboard/src/utils/layout.ts", + "lineRange": [ + 7, + 45 + ], + "summary": "Runs Dagre layout on React Flow nodes and edges, returning computed positions.", + "tags": [ + "utility", + "layout", + "dagre" + ], + "complexity": "simple" + }, + { + "id": "file:packages/dashboard/src/components/GraphView.tsx", + "type": "file", + "name": "GraphView.tsx", + "filePath": "packages/dashboard/src/components/GraphView.tsx", + "summary": "React Flow-based interactive graph visualization with Dagre layout, persona-based filtering, layer grouping, and tour highlighting.", + "tags": [ + "visualization", + "react-flow", + "graph", + "layer-grouping", + "persona-adaptive" + ], + "complexity": "complex" + }, + { + "id": "func:packages/dashboard/src/components/GraphView.tsx:GraphView", + "type": "function", + "name": "GraphView", + "filePath": "packages/dashboard/src/components/GraphView.tsx", + "lineRange": [ + 23, + 243 + ], + "summary": "Renders the React Flow canvas with knowledge graph data, handling persona filtering, Dagre layout, layer groups, and node selection.", + "tags": [ + "react-component", + "graph", + "visualization" + ], + "complexity": "complex" + }, + { + "id": "file:packages/dashboard/src/components/ChatPanel.tsx", + "type": "file", + "name": "ChatPanel.tsx", + "filePath": "packages/dashboard/src/components/ChatPanel.tsx", + "summary": "Chat interface panel managing API key input, message rendering with react-markdown, auto-scroll, and user input.", + "tags": [ + "chat", + "ui-component", + "react", + "markdown", + "api-key" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/dashboard/src/components/ChatPanel.tsx:ChatPanel", + "type": "function", + "name": "ChatPanel", + "filePath": "packages/dashboard/src/components/ChatPanel.tsx", + "lineRange": [ + 5, + 253 + ], + "summary": "Chat panel component handling API key setup, markdown message display, loading state, and keyboard shortcuts.", + "tags": [ + "react-component", + "chat", + "ui-component" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/dashboard/src/components/CodeViewer.tsx", + "type": "file", + "name": "CodeViewer.tsx", + "filePath": "packages/dashboard/src/components/CodeViewer.tsx", + "summary": "Monaco Editor-based code viewer displaying metadata and placeholder source code for selected graph nodes.", + "tags": [ + "component", + "monaco-editor", + "code-viewer", + "ui" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/dashboard/src/components/CodeViewer.tsx:getLanguage", + "type": "function", + "name": "getLanguage", + "filePath": "packages/dashboard/src/components/CodeViewer.tsx", + "lineRange": [ + 31, + 35 + ], + "summary": "Maps a file path's extension to a Monaco Editor language identifier.", + "tags": [ + "utility", + "language-detection", + "monaco" + ], + "complexity": "simple" + }, + { + "id": "func:packages/dashboard/src/components/CodeViewer.tsx:CodeViewer", + "type": "function", + "name": "CodeViewer", + "filePath": "packages/dashboard/src/components/CodeViewer.tsx", + "lineRange": [ + 37, + 114 + ], + "summary": "React component rendering a read-only Monaco Editor panel for the selected graph node.", + "tags": [ + "component", + "react", + "ui", + "code-viewer" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/dashboard/src/components/CustomNode.tsx", + "type": "file", + "name": "CustomNode.tsx", + "filePath": "packages/dashboard/src/components/CustomNode.tsx", + "summary": "Custom React Flow node component with type-based colors, complexity badges, and highlight rings.", + "tags": [ + "component", + "react-flow", + "graph", + "ui", + "visualization" + ], + "complexity": "moderate" + }, + { + "id": "class:packages/dashboard/src/components/CustomNode.tsx:CustomNodeData", + "type": "class", + "name": "CustomNodeData", + "filePath": "packages/dashboard/src/components/CustomNode.tsx", + "lineRange": [ + 39, + 48 + ], + "summary": "TypeScript interface defining the data shape for a custom React Flow node.", + "tags": [ + "interface", + "data-model", + "react-flow" + ], + "complexity": "simple" + }, + { + "id": "func:packages/dashboard/src/components/CustomNode.tsx:CustomNode", + "type": "function", + "name": "CustomNode", + "filePath": "packages/dashboard/src/components/CustomNode.tsx", + "lineRange": [ + 52, + 116 + ], + "summary": "Custom React Flow node rendering type, complexity, name, summary, and dynamic highlight styles.", + "tags": [ + "component", + "react-flow", + "ui", + "graph" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/dashboard/src/components/LayerLegend.tsx", + "type": "file", + "name": "LayerLegend.tsx", + "filePath": "packages/dashboard/src/components/LayerLegend.tsx", + "summary": "Layer color constants, color-getter utilities, and a LayerLegend UI component.", + "tags": [ + "component", + "layer-visualization", + "ui", + "legend" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/dashboard/src/components/LayerLegend.tsx:getLayerColor", + "type": "function", + "name": "getLayerColor", + "filePath": "packages/dashboard/src/components/LayerLegend.tsx", + "lineRange": [ + 27, + 29 + ], + "summary": "Returns the background RGBA color for a layer index.", + "tags": [ + "utility", + "color", + "layer" + ], + "complexity": "simple" + }, + { + "id": "func:packages/dashboard/src/components/LayerLegend.tsx:getLayerBorderColor", + "type": "function", + "name": "getLayerBorderColor", + "filePath": "packages/dashboard/src/components/LayerLegend.tsx", + "lineRange": [ + 31, + 33 + ], + "summary": "Returns the border RGBA color for a layer index.", + "tags": [ + "utility", + "color", + "layer" + ], + "complexity": "simple" + }, + { + "id": "func:packages/dashboard/src/components/LayerLegend.tsx:LayerLegend", + "type": "function", + "name": "LayerLegend", + "filePath": "packages/dashboard/src/components/LayerLegend.tsx", + "lineRange": [ + 35, + 86 + ], + "summary": "Toggle button for layer grouping and inline legend of layer names with color indicators.", + "tags": [ + "component", + "ui", + "layer-visualization" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/dashboard/src/components/LearnPanel.tsx", + "type": "file", + "name": "LearnPanel.tsx", + "filePath": "packages/dashboard/src/components/LearnPanel.tsx", + "summary": "Guided learning/tour panel managing three states (no tour, ready, active) with step navigation and markdown.", + "tags": [ + "component", + "tour", + "learning", + "ui", + "markdown" + ], + "complexity": "complex" + }, + { + "id": "func:packages/dashboard/src/components/LearnPanel.tsx:LearnPanel", + "type": "function", + "name": "LearnPanel", + "filePath": "packages/dashboard/src/components/LearnPanel.tsx", + "lineRange": [ + 5, + 228 + ], + "summary": "Guided tour UI with state-machine rendering for empty, idle, and active phases including progress bar.", + "tags": [ + "component", + "tour", + "ui", + "learning" + ], + "complexity": "complex" + }, + { + "id": "file:packages/dashboard/src/components/NodeInfo.tsx", + "type": "file", + "name": "NodeInfo.tsx", + "filePath": "packages/dashboard/src/components/NodeInfo.tsx", + "summary": "Detail panel for selected graph node displaying type, complexity, summary, AI explain, tags, and connections.", + "tags": [ + "component", + "node-detail", + "ui", + "markdown" + ], + "complexity": "complex" + }, + { + "id": "func:packages/dashboard/src/components/NodeInfo.tsx:NodeInfo", + "type": "function", + "name": "NodeInfo", + "filePath": "packages/dashboard/src/components/NodeInfo.tsx", + "lineRange": [ + 19, + 196 + ], + "summary": "Comprehensive node metadata panel with LLM explanation trigger, tags, and connections list.", + "tags": [ + "component", + "node-detail", + "ui" + ], + "complexity": "complex" + }, + { + "id": "file:packages/dashboard/src/components/PersonaSelector.tsx", + "type": "file", + "name": "PersonaSelector.tsx", + "filePath": "packages/dashboard/src/components/PersonaSelector.tsx", + "summary": "Compact toggle button group for switching between three dashboard personas.", + "tags": [ + "component", + "persona", + "ui", + "settings" + ], + "complexity": "simple" + }, + { + "id": "func:packages/dashboard/src/components/PersonaSelector.tsx:PersonaSelector", + "type": "function", + "name": "PersonaSelector", + "filePath": "packages/dashboard/src/components/PersonaSelector.tsx", + "lineRange": [ + 22, + 44 + ], + "summary": "Segmented button group for persona selection with active highlighting.", + "tags": [ + "component", + "persona", + "ui" + ], + "complexity": "simple" + }, + { + "id": "file:packages/dashboard/src/components/SearchBar.tsx", + "type": "file", + "name": "SearchBar.tsx", + "filePath": "packages/dashboard/src/components/SearchBar.tsx", + "summary": "Search bar with fuzzy/semantic mode toggle, live dropdown results, and keyboard dismissal.", + "tags": [ + "component", + "search", + "ui", + "fuzzy", + "semantic" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/dashboard/src/components/SearchBar.tsx:SearchBar", + "type": "function", + "name": "SearchBar", + "filePath": "packages/dashboard/src/components/SearchBar.tsx", + "lineRange": [ + 12, + 177 + ], + "summary": "Search input with mode toggle, live top-5 results dropdown, and escape/outside-click handling.", + "tags": [ + "component", + "search", + "ui" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/skill/src/index.ts", + "type": "file", + "name": "index.ts", + "filePath": "packages/skill/src/index.ts", + "summary": "Barrel entry point for the skill package, re-exporting all public functions and types.", + "tags": [ + "entry-point", + "barrel", + "exports", + "skill" + ], + "complexity": "simple" + }, + { + "id": "file:packages/skill/src/context-builder.ts", + "type": "file", + "name": "context-builder.ts", + "filePath": "packages/skill/src/context-builder.ts", + "summary": "Builds ChatContext from a KnowledgeGraph by fuzzy-searching and expanding 1-hop via graph edges.", + "tags": [ + "chat", + "context", + "graph-traversal", + "llm", + "search" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/skill/src/context-builder.ts:buildChatContext", + "type": "function", + "name": "buildChatContext", + "filePath": "packages/skill/src/context-builder.ts", + "lineRange": [ + 25, + 80 + ], + "summary": "Searches the KnowledgeGraph for matching nodes, expands 1 hop, returns structured ChatContext.", + "tags": [ + "chat", + "graph-traversal", + "search", + "context-builder" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/skill/src/context-builder.ts:formatContextForPrompt", + "type": "function", + "name": "formatContextForPrompt", + "filePath": "packages/skill/src/context-builder.ts", + "lineRange": [ + 85, + 147 + ], + "summary": "Converts ChatContext into markdown suitable for LLM prompt injection.", + "tags": [ + "formatting", + "markdown", + "llm", + "prompt" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/skill/src/diff-analyzer.ts", + "type": "file", + "name": "diff-analyzer.ts", + "filePath": "packages/skill/src/diff-analyzer.ts", + "summary": "Maps git-changed files to graph nodes and identifies downstream ripple effects with risk assessment.", + "tags": [ + "diff", + "impact-analysis", + "risk", + "graph-traversal", + "llm" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/skill/src/diff-analyzer.ts:buildDiffContext", + "type": "function", + "name": "buildDiffContext", + "filePath": "packages/skill/src/diff-analyzer.ts", + "lineRange": [ + 22, + 88 + ], + "summary": "Maps changed file paths to graph nodes and expands to find all impacted nodes, edges, and layers.", + "tags": [ + "diff", + "graph-traversal", + "impact-analysis", + "context-builder" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/skill/src/diff-analyzer.ts:formatDiffAnalysis", + "type": "function", + "name": "formatDiffAnalysis", + "filePath": "packages/skill/src/diff-analyzer.ts", + "lineRange": [ + 93, + 198 + ], + "summary": "Renders DiffContext as structured markdown with risk assessment.", + "tags": [ + "formatting", + "markdown", + "diff", + "risk-assessment" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/skill/src/explain-builder.ts", + "type": "file", + "name": "explain-builder.ts", + "filePath": "packages/skill/src/explain-builder.ts", + "summary": "Builds ExplainContext for a file or function path with neighbors and layer info.", + "tags": [ + "explain", + "context-builder", + "graph-traversal", + "llm", + "prompt" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/skill/src/explain-builder.ts:buildExplainContext", + "type": "function", + "name": "buildExplainContext", + "filePath": "packages/skill/src/explain-builder.ts", + "lineRange": [ + 22, + 103 + ], + "summary": "Resolves a file/function string to a graph node with children and 1-hop neighbors.", + "tags": [ + "explain", + "graph-traversal", + "context-builder", + "node-resolution" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/skill/src/explain-builder.ts:formatExplainPrompt", + "type": "function", + "name": "formatExplainPrompt", + "filePath": "packages/skill/src/explain-builder.ts", + "lineRange": [ + 108, + 196 + ], + "summary": "Converts ExplainContext into a structured LLM explanation prompt.", + "tags": [ + "formatting", + "markdown", + "llm", + "prompt", + "explain" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/skill/src/onboard-builder.ts", + "type": "file", + "name": "onboard-builder.ts", + "filePath": "packages/skill/src/onboard-builder.ts", + "summary": "Generates a standalone markdown onboarding guide from a KnowledgeGraph.", + "tags": [ + "onboarding", + "documentation", + "markdown", + "knowledge-graph" + ], + "complexity": "moderate" + }, + { + "id": "func:packages/skill/src/onboard-builder.ts:buildOnboardingGuide", + "type": "function", + "name": "buildOnboardingGuide", + "filePath": "packages/skill/src/onboard-builder.ts", + "lineRange": [ + 7, + 124 + ], + "summary": "Renders a complete onboarding markdown document from a KnowledgeGraph.", + "tags": [ + "onboarding", + "documentation", + "markdown", + "tour" + ], + "complexity": "moderate" + }, + { + "id": "file:packages/skill/src/understand-chat.ts", + "type": "file", + "name": "understand-chat.ts", + "filePath": "packages/skill/src/understand-chat.ts", + "summary": "Thin skill handler composing buildChatContext and formatContextForPrompt into buildChatPrompt.", + "tags": [ + "chat", + "skill", + "llm", + "prompt" + ], + "complexity": "simple" + }, + { + "id": "func:packages/skill/src/understand-chat.ts:buildChatPrompt", + "type": "function", + "name": "buildChatPrompt", + "filePath": "packages/skill/src/understand-chat.ts", + "lineRange": [ + 8, + 29 + ], + "summary": "Builds a complete LLM chat prompt by composing graph context with a system instruction.", + "tags": [ + "chat", + "prompt", + "llm", + "composition" + ], + "complexity": "simple" + } + ], + "edges": [ + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/schema.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/search.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/staleness.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/embedding-search.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/persistence/index.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/analyzer/graph-builder.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/analyzer/llm-analyzer.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/analyzer/layer-detector.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/analyzer/tour-generator.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/analyzer/language-lesson.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/plugins/registry.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/index.ts", + "target": "file:packages/core/src/plugins/discovery.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/schema.ts", + "target": "file:packages/core/src/types.ts", + "type": "depends_on", + "direction": "forward", + "weight": 0.6 + }, + { + "source": "file:packages/core/src/search.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/staleness.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/embedding-search.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/embedding-search.ts", + "target": "file:packages/core/src/search.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/schema.ts", + "target": "func:packages/core/src/schema.ts:validateGraph", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/search.ts", + "target": "class:packages/core/src/search.ts:SearchEngine", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/embedding-search.ts", + "target": "class:packages/core/src/embedding-search.ts:SemanticSearchEngine", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/embedding-search.ts", + "target": "func:packages/core/src/embedding-search.ts:cosineSimilarity", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/staleness.ts", + "target": "func:packages/core/src/staleness.ts:getChangedFiles", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/staleness.ts", + "target": "func:packages/core/src/staleness.ts:isStale", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/staleness.ts", + "target": "func:packages/core/src/staleness.ts:mergeGraphUpdate", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "func:packages/core/src/staleness.ts:isStale", + "target": "func:packages/core/src/staleness.ts:getChangedFiles", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/embedding-search.ts:SemanticSearchEngine", + "target": "func:packages/core/src/embedding-search.ts:cosineSimilarity", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/embedding-search.ts:SemanticSearchEngine", + "target": "class:packages/core/src/search.ts:SearchEngine", + "type": "similar_to", + "direction": "bidirectional", + "weight": 0.6 + }, + { + "source": "file:packages/core/src/schema.ts", + "target": "file:packages/core/src/types.ts", + "type": "validates", + "direction": "forward", + "weight": 0.9 + }, + { + "source": "file:packages/core/src/analyzer/graph-builder.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/analyzer/graph-builder.ts", + "target": "class:packages/core/src/analyzer/graph-builder.ts:GraphBuilder", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/graph-builder.ts", + "target": "func:packages/core/src/analyzer/graph-builder.ts:detectLanguage", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/graph-builder.ts", + "target": "class:packages/core/src/analyzer/graph-builder.ts:GraphBuilder", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:buildFileAnalysisPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:buildProjectSummaryPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:parseFileAnalysisResponse", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:parseProjectSummaryResponse", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:buildFileAnalysisPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:buildProjectSummaryPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:parseFileAnalysisResponse", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/llm-analyzer.ts", + "target": "func:packages/core/src/analyzer/llm-analyzer.ts:parseProjectSummaryResponse", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:detectLayers", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:buildLayerDetectionPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:parseLayerDetectionResponse", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:applyLLMLayers", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:detectLayers", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:buildLayerDetectionPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:parseLayerDetectionResponse", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/layer-detector.ts", + "target": "func:packages/core/src/analyzer/layer-detector.ts:applyLLMLayers", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/language-lesson.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/analyzer/language-lesson.ts", + "target": "func:packages/core/src/analyzer/language-lesson.ts:detectLanguageConcepts", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/language-lesson.ts", + "target": "func:packages/core/src/analyzer/language-lesson.ts:buildLanguageLessonPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/language-lesson.ts", + "target": "func:packages/core/src/analyzer/language-lesson.ts:parseLanguageLessonResponse", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/language-lesson.ts", + "target": "func:packages/core/src/analyzer/language-lesson.ts:detectLanguageConcepts", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/language-lesson.ts", + "target": "func:packages/core/src/analyzer/language-lesson.ts:buildLanguageLessonPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/language-lesson.ts", + "target": "func:packages/core/src/analyzer/language-lesson.ts:parseLanguageLessonResponse", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/core/src/analyzer/language-lesson.ts:buildLanguageLessonPrompt", + "target": "func:packages/core/src/analyzer/language-lesson.ts:detectLanguageConcepts", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/tour-generator.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/analyzer/tour-generator.ts", + "target": "func:packages/core/src/analyzer/tour-generator.ts:buildTourGenerationPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/tour-generator.ts", + "target": "func:packages/core/src/analyzer/tour-generator.ts:parseTourGenerationResponse", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/tour-generator.ts", + "target": "func:packages/core/src/analyzer/tour-generator.ts:generateHeuristicTour", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/analyzer/tour-generator.ts", + "target": "func:packages/core/src/analyzer/tour-generator.ts:buildTourGenerationPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/tour-generator.ts", + "target": "func:packages/core/src/analyzer/tour-generator.ts:parseTourGenerationResponse", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/tour-generator.ts", + "target": "func:packages/core/src/analyzer/tour-generator.ts:generateHeuristicTour", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/analyzer/graph-builder.ts", + "target": "file:packages/core/src/analyzer/llm-analyzer.ts", + "type": "related", + "direction": "forward", + "weight": 0.6 + }, + { + "source": "file:packages/core/src/analyzer/graph-builder.ts", + "target": "file:packages/core/src/analyzer/layer-detector.ts", + "type": "related", + "direction": "forward", + "weight": 0.6 + }, + { + "source": "file:packages/core/src/analyzer/graph-builder.ts", + "target": "file:packages/core/src/analyzer/tour-generator.ts", + "type": "related", + "direction": "forward", + "weight": 0.6 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:languageKeyFromPath", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:traverse", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:getStringValue", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractParams", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractReturnType", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractImportSpecifiers", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "target": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:languageKeyFromPath", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractParams", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractReturnType", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:extractImportSpecifiers", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "target": "func:packages/core/src/plugins/tree-sitter-plugin.ts:getStringValue", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/plugins/registry.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/plugins/registry.ts", + "target": "class:packages/core/src/plugins/registry.ts:PluginRegistry", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/registry.ts", + "target": "class:packages/core/src/plugins/registry.ts:PluginRegistry", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/plugins/discovery.ts", + "target": "func:packages/core/src/plugins/discovery.ts:parsePluginConfig", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/discovery.ts", + "target": "func:packages/core/src/plugins/discovery.ts:serializePluginConfig", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/plugins/discovery.ts", + "target": "func:packages/core/src/plugins/discovery.ts:parsePluginConfig", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/plugins/discovery.ts", + "target": "func:packages/core/src/plugins/discovery.ts:serializePluginConfig", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "file:packages/core/src/types.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "file:packages/core/src/schema.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:saveGraph", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:loadGraph", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:saveMeta", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:loadMeta", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:saveGraph", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:loadGraph", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:saveMeta", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/core/src/persistence/index.ts", + "target": "func:packages/core/src/persistence/index.ts:loadMeta", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/core/src/persistence/index.ts:loadGraph", + "target": "func:packages/core/src/schema.ts:validateGraph", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "class:packages/core/src/plugins/registry.ts:PluginRegistry", + "target": "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "type": "related", + "direction": "forward", + "weight": 0.6 + }, + { + "source": "file:packages/dashboard/src/main.tsx", + "target": "file:packages/dashboard/src/App.tsx", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/App.tsx", + "target": "func:packages/dashboard/src/App.tsx:App", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/App.tsx", + "target": "func:packages/dashboard/src/App.tsx:App", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/App.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/App.tsx", + "target": "file:packages/dashboard/src/components/GraphView.tsx", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/App.tsx", + "target": "file:packages/dashboard/src/components/ChatPanel.tsx", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/store.ts", + "target": "func:packages/dashboard/src/store.ts:buildSystemPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/store.ts", + "target": "func:packages/dashboard/src/store.ts:getSortedTour", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/store.ts", + "target": "func:packages/dashboard/src/store.ts:useDashboardStore", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/store.ts", + "target": "func:packages/dashboard/src/store.ts:useDashboardStore", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/dashboard/src/store.ts:useDashboardStore", + "target": "func:packages/dashboard/src/store.ts:buildSystemPrompt", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/dashboard/src/store.ts:useDashboardStore", + "target": "func:packages/dashboard/src/store.ts:getSortedTour", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/utils/layout.ts", + "target": "func:packages/dashboard/src/utils/layout.ts:applyDagreLayout", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/utils/layout.ts", + "target": "func:packages/dashboard/src/utils/layout.ts:applyDagreLayout", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/GraphView.tsx", + "target": "func:packages/dashboard/src/components/GraphView.tsx:GraphView", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/GraphView.tsx", + "target": "func:packages/dashboard/src/components/GraphView.tsx:GraphView", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/GraphView.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/components/GraphView.tsx", + "target": "file:packages/dashboard/src/utils/layout.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "func:packages/dashboard/src/components/GraphView.tsx:GraphView", + "target": "func:packages/dashboard/src/utils/layout.ts:applyDagreLayout", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/dashboard/src/components/GraphView.tsx:GraphView", + "target": "func:packages/dashboard/src/store.ts:useDashboardStore", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/ChatPanel.tsx", + "target": "func:packages/dashboard/src/components/ChatPanel.tsx:ChatPanel", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/ChatPanel.tsx", + "target": "func:packages/dashboard/src/components/ChatPanel.tsx:ChatPanel", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/ChatPanel.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "func:packages/dashboard/src/components/ChatPanel.tsx:ChatPanel", + "target": "func:packages/dashboard/src/store.ts:useDashboardStore", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/dashboard/src/App.tsx:App", + "target": "func:packages/dashboard/src/store.ts:useDashboardStore", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/CodeViewer.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/components/CodeViewer.tsx", + "target": "func:packages/dashboard/src/components/CodeViewer.tsx:getLanguage", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/CodeViewer.tsx", + "target": "func:packages/dashboard/src/components/CodeViewer.tsx:CodeViewer", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/CodeViewer.tsx", + "target": "func:packages/dashboard/src/components/CodeViewer.tsx:CodeViewer", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/dashboard/src/components/CodeViewer.tsx:CodeViewer", + "target": "func:packages/dashboard/src/components/CodeViewer.tsx:getLanguage", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/CustomNode.tsx", + "target": "class:packages/dashboard/src/components/CustomNode.tsx:CustomNodeData", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/CustomNode.tsx", + "target": "func:packages/dashboard/src/components/CustomNode.tsx:CustomNode", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/CustomNode.tsx", + "target": "func:packages/dashboard/src/components/CustomNode.tsx:CustomNode", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/CustomNode.tsx", + "target": "class:packages/dashboard/src/components/CustomNode.tsx:CustomNodeData", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/LayerLegend.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/components/LayerLegend.tsx", + "target": "func:packages/dashboard/src/components/LayerLegend.tsx:getLayerColor", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/LayerLegend.tsx", + "target": "func:packages/dashboard/src/components/LayerLegend.tsx:getLayerBorderColor", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/LayerLegend.tsx", + "target": "func:packages/dashboard/src/components/LayerLegend.tsx:LayerLegend", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/LayerLegend.tsx", + "target": "func:packages/dashboard/src/components/LayerLegend.tsx:getLayerColor", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/LayerLegend.tsx", + "target": "func:packages/dashboard/src/components/LayerLegend.tsx:getLayerBorderColor", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/LayerLegend.tsx", + "target": "func:packages/dashboard/src/components/LayerLegend.tsx:LayerLegend", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/dashboard/src/components/LayerLegend.tsx:LayerLegend", + "target": "func:packages/dashboard/src/components/LayerLegend.tsx:getLayerBorderColor", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/LearnPanel.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/components/LearnPanel.tsx", + "target": "func:packages/dashboard/src/components/LearnPanel.tsx:LearnPanel", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/LearnPanel.tsx", + "target": "func:packages/dashboard/src/components/LearnPanel.tsx:LearnPanel", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/NodeInfo.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/components/NodeInfo.tsx", + "target": "func:packages/dashboard/src/components/NodeInfo.tsx:NodeInfo", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/NodeInfo.tsx", + "target": "func:packages/dashboard/src/components/NodeInfo.tsx:NodeInfo", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/PersonaSelector.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/components/PersonaSelector.tsx", + "target": "func:packages/dashboard/src/components/PersonaSelector.tsx:PersonaSelector", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/PersonaSelector.tsx", + "target": "func:packages/dashboard/src/components/PersonaSelector.tsx:PersonaSelector", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/dashboard/src/components/SearchBar.tsx", + "target": "file:packages/dashboard/src/store.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/dashboard/src/components/SearchBar.tsx", + "target": "func:packages/dashboard/src/components/SearchBar.tsx:SearchBar", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/dashboard/src/components/SearchBar.tsx", + "target": "func:packages/dashboard/src/components/SearchBar.tsx:SearchBar", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/index.ts", + "target": "file:packages/skill/src/context-builder.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/skill/src/index.ts", + "target": "file:packages/skill/src/understand-chat.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/skill/src/index.ts", + "target": "file:packages/skill/src/diff-analyzer.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/skill/src/index.ts", + "target": "file:packages/skill/src/explain-builder.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/skill/src/index.ts", + "target": "file:packages/skill/src/onboard-builder.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "file:packages/skill/src/context-builder.ts", + "target": "func:packages/skill/src/context-builder.ts:buildChatContext", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/context-builder.ts", + "target": "func:packages/skill/src/context-builder.ts:formatContextForPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/diff-analyzer.ts", + "target": "func:packages/skill/src/diff-analyzer.ts:buildDiffContext", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/diff-analyzer.ts", + "target": "func:packages/skill/src/diff-analyzer.ts:formatDiffAnalysis", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/explain-builder.ts", + "target": "func:packages/skill/src/explain-builder.ts:buildExplainContext", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/explain-builder.ts", + "target": "func:packages/skill/src/explain-builder.ts:formatExplainPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/onboard-builder.ts", + "target": "func:packages/skill/src/onboard-builder.ts:buildOnboardingGuide", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/understand-chat.ts", + "target": "func:packages/skill/src/understand-chat.ts:buildChatPrompt", + "type": "contains", + "direction": "forward", + "weight": 1 + }, + { + "source": "file:packages/skill/src/understand-chat.ts", + "target": "file:packages/skill/src/context-builder.ts", + "type": "imports", + "direction": "forward", + "weight": 0.7 + }, + { + "source": "func:packages/skill/src/understand-chat.ts:buildChatPrompt", + "target": "func:packages/skill/src/context-builder.ts:buildChatContext", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/skill/src/understand-chat.ts:buildChatPrompt", + "target": "func:packages/skill/src/context-builder.ts:formatContextForPrompt", + "type": "calls", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/context-builder.ts", + "target": "func:packages/skill/src/context-builder.ts:formatContextForPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/context-builder.ts", + "target": "func:packages/skill/src/context-builder.ts:buildChatContext", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/diff-analyzer.ts", + "target": "func:packages/skill/src/diff-analyzer.ts:buildDiffContext", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/diff-analyzer.ts", + "target": "func:packages/skill/src/diff-analyzer.ts:formatDiffAnalysis", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/explain-builder.ts", + "target": "func:packages/skill/src/explain-builder.ts:buildExplainContext", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/explain-builder.ts", + "target": "func:packages/skill/src/explain-builder.ts:formatExplainPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/onboard-builder.ts", + "target": "func:packages/skill/src/onboard-builder.ts:buildOnboardingGuide", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "file:packages/skill/src/understand-chat.ts", + "target": "func:packages/skill/src/understand-chat.ts:buildChatPrompt", + "type": "exports", + "direction": "forward", + "weight": 0.8 + }, + { + "source": "func:packages/skill/src/context-builder.ts:buildChatContext", + "target": "func:packages/skill/src/context-builder.ts:formatContextForPrompt", + "type": "related", + "direction": "forward", + "weight": 0.6 + }, + { + "source": "func:packages/skill/src/diff-analyzer.ts:buildDiffContext", + "target": "func:packages/skill/src/diff-analyzer.ts:formatDiffAnalysis", + "type": "related", + "direction": "forward", + "weight": 0.6 + }, + { + "source": "func:packages/skill/src/explain-builder.ts:buildExplainContext", + "target": "func:packages/skill/src/explain-builder.ts:formatExplainPrompt", + "type": "related", + "direction": "forward", + "weight": 0.6 + } + ], + "layers": [ + { + "id": "layer:types", + "name": "Types & Schema Layer", + "description": "Core TypeScript type definitions and runtime schema validation that form the shared data contract across all packages", + "nodeIds": [ + "file:packages/core/src/types.ts", + "file:packages/core/src/schema.ts" + ] + }, + { + "id": "layer:analysis-engine", + "name": "Analysis Engine Layer", + "description": "Static analysis, graph construction, LLM-driven enrichment, layer detection, tour generation, and language lesson extraction", + "nodeIds": [ + "file:packages/core/src/analyzer/graph-builder.ts", + "file:packages/core/src/analyzer/llm-analyzer.ts", + "file:packages/core/src/analyzer/layer-detector.ts", + "file:packages/core/src/analyzer/language-lesson.ts", + "file:packages/core/src/analyzer/tour-generator.ts" + ] + }, + { + "id": "layer:plugin", + "name": "Plugin & Persistence Layer", + "description": "Extensible plugin system for language-specific static analysis, plugin registry and discovery, and knowledge graph persistence", + "nodeIds": [ + "file:packages/core/src/plugins/tree-sitter-plugin.ts", + "file:packages/core/src/plugins/registry.ts", + "file:packages/core/src/plugins/discovery.ts", + "file:packages/core/src/persistence/index.ts" + ] + }, + { + "id": "layer:search", + "name": "Search & Core Services Layer", + "description": "Cross-cutting core services including fuzzy search, semantic search, staleness detection, and barrel entry point", + "nodeIds": [ + "file:packages/core/src/search.ts", + "file:packages/core/src/embedding-search.ts", + "file:packages/core/src/staleness.ts", + "file:packages/core/src/index.ts" + ] + }, + { + "id": "layer:skill", + "name": "Skill (CLI Command) Layer", + "description": "Claude Code skill handlers implementing the /understand-* commands", + "nodeIds": [ + "file:packages/skill/src/context-builder.ts", + "file:packages/skill/src/understand-chat.ts", + "file:packages/skill/src/diff-analyzer.ts", + "file:packages/skill/src/explain-builder.ts", + "file:packages/skill/src/onboard-builder.ts", + "file:packages/skill/src/index.ts" + ] + }, + { + "id": "layer:state", + "name": "State Management Layer", + "description": "Zustand store holding all dashboard application state plus the dagre layout utility", + "nodeIds": [ + "file:packages/dashboard/src/store.ts", + "file:packages/dashboard/src/utils/layout.ts" + ] + }, + { + "id": "layer:ui", + "name": "UI & Presentation Layer", + "description": "React dashboard components and application entry points", + "nodeIds": [ + "file:packages/dashboard/src/App.tsx", + "file:packages/dashboard/src/main.tsx", + "file:packages/dashboard/src/components/GraphView.tsx", + "file:packages/dashboard/src/components/ChatPanel.tsx", + "file:packages/dashboard/src/components/CodeViewer.tsx", + "file:packages/dashboard/src/components/CustomNode.tsx", + "file:packages/dashboard/src/components/LayerLegend.tsx", + "file:packages/dashboard/src/components/LearnPanel.tsx", + "file:packages/dashboard/src/components/NodeInfo.tsx", + "file:packages/dashboard/src/components/PersonaSelector.tsx", + "file:packages/dashboard/src/components/SearchBar.tsx" + ] + } + ], + "tour": [ + { + "order": 1, + "title": "Project Overview: The Dashboard Entry Point", + "description": "Start with packages/dashboard/src/App.tsx, the root React component that bootstraps the entire interactive dashboard. On mount it fetches a pre-built knowledge-graph.json file and hands it to the Zustand store. From here you can see the three persona-adaptive layouts and how every major panel is composed together.", + "nodeIds": [ + "func:packages/dashboard/src/App.tsx:App" + ], + "languageLesson": "TypeScript conditional JSX with ternary chains is a clean pattern for persona-adaptive rendering without introducing a separate routing library." + }, + { + "order": 2, + "title": "The Domain Model: Core Types", + "description": "Every part of the system speaks the same language defined in packages/core/src/types.ts. GraphNode, GraphEdge, Layer, TourStep, KnowledgeGraph, and AnalyzerPlugin are the vocabulary of the entire project. The 18 EdgeType variants across five categories capture a rich set of code relationships.", + "nodeIds": [ + "file:packages/core/src/types.ts" + ], + "languageLesson": "TypeScript discriminated union types enable exhaustive switch checks and IDE autocomplete across the entire codebase with zero runtime cost." + }, + { + "order": 3, + "title": "Runtime Validation: Zod Schema", + "description": "packages/core/src/schema.ts mirrors every type from types.ts using Zod, adding runtime validation at the boundary where JSON is loaded from disk. The persistence layer imports schema.ts directly, so any malformed graph is rejected before it can corrupt dashboard state.", + "nodeIds": [ + "file:packages/core/src/schema.ts" + ], + "languageLesson": "Zod v4 schema definitions provide runtime safety. Using z.infer derives the TypeScript type from the schema itself, keeping the two in sync." + }, + { + "order": 4, + "title": "Building the Graph: GraphBuilder", + "description": "packages/core/src/analyzer/graph-builder.ts is the stateful assembly point for the knowledge graph. It accepts addFile, addFileWithAnalysis, addImportEdge, and addCallEdge calls, accumulating nodes and edges, then emits the final KnowledgeGraph via build().", + "nodeIds": [ + "class:packages/core/src/analyzer/graph-builder.ts:GraphBuilder" + ], + "languageLesson": "The Builder pattern in TypeScript is preferable to constructor overloads when an object requires many optional, ordered setup steps." + }, + { + "order": 5, + "title": "Static Analysis: The Plugin System", + "description": "The plugin system separates how to parse a language from the rest of the pipeline. PluginRegistry routes by extension to the right AnalyzerPlugin. TreeSitterPlugin uses web-tree-sitter WASM to parse TS/JS into ASTs and extract functions, classes, imports, and call graphs.", + "nodeIds": [ + "class:packages/core/src/plugins/registry.ts:PluginRegistry", + "class:packages/core/src/plugins/tree-sitter-plugin.ts:TreeSitterPlugin", + "file:packages/core/src/plugins/discovery.ts" + ], + "languageLesson": "The AnalyzerPlugin interface is structural — any object with matching method signatures satisfies it, enabling community plugins without base class inheritance." + }, + { + "order": 6, + "title": "LLM-Augmented Analysis", + "description": "Static analysis gives structure; LLM analysis gives meaning. llm-analyzer.ts builds prompts requesting JSON summaries per file. layer-detector.ts applies filename heuristics then optionally asks the LLM to group nodes into architectural layers.", + "nodeIds": [ + "file:packages/core/src/analyzer/llm-analyzer.ts", + "file:packages/core/src/analyzer/layer-detector.ts" + ] + }, + { + "order": 7, + "title": "Tour Generation: Teaching a Codebase", + "description": "tour-generator.ts generates guided tours using Kahn's topological sort algorithm for dependency-respecting traversal order, grouping results by architectural layer. The TourStep data structure in types.ts is exactly what drives this tour.", + "nodeIds": [ + "file:packages/core/src/analyzer/tour-generator.ts" + ], + "languageLesson": "Kahn's algorithm processes a DAG by repeatedly removing zero in-degree nodes. In TypeScript this is elegantly expressed with a Map and queue array." + }, + { + "order": 8, + "title": "Search: Fuzzy and Semantic Modes", + "description": "SearchEngine wraps Fuse.js for weighted fuzzy matching. SemanticSearchEngine uses cosine similarity over embeddings. Both return results in the same shape (lower score = better match), so the dashboard can toggle between modes seamlessly.", + "nodeIds": [ + "file:packages/core/src/search.ts", + "file:packages/core/src/embedding-search.ts" + ], + "languageLesson": "Both engines adopt score = 0 (perfect) to 1 (no match). SemanticSearchEngine translates cosine similarity via score = 1 - similarity." + }, + { + "order": 9, + "title": "Infrastructure: Persistence and Staleness", + "description": "persistence/index.ts handles saving/loading KnowledgeGraph JSON with Zod validation. staleness.ts uses git diff to detect outdated graphs and mergeGraphUpdate performs surgical incremental updates.", + "nodeIds": [ + "file:packages/core/src/persistence/index.ts", + "file:packages/core/src/staleness.ts" + ] + }, + { + "order": 10, + "title": "Dashboard State: The Zustand Store", + "description": "store.ts is the single source of truth for everything the dashboard displays. It holds the graph, search state, chat history, tour state, and persona. buildSystemPrompt assembles rich LLM context for the ChatPanel.", + "nodeIds": [ + "func:packages/dashboard/src/store.ts:useDashboardStore" + ], + "languageLesson": "Zustand's create pattern is a TypeScript-idiomatic alternative to Redux. Selectors subscribe only to changed slices." + }, + { + "order": 11, + "title": "Visual Graph: React Flow with Dagre Layout", + "description": "GraphView.tsx renders the knowledge graph as an interactive node-link diagram using React Flow. applyDagreLayout computes hierarchical positions, and tour-highlighted nodes receive distinct visual styles.", + "nodeIds": [ + "func:packages/dashboard/src/components/GraphView.tsx:GraphView" + ] + }, + { + "order": 12, + "title": "Skill Commands: AI-Powered Developer Tools", + "description": "The skill package exposes four Claude Code slash commands. context-builder.ts does fuzzy search + 1-hop expansion. diff-analyzer.ts traces ripple effects from git diffs. explain-builder.ts resolves nodes for explanation. onboard-builder.ts generates markdown onboarding guides.", + "nodeIds": [ + "func:packages/skill/src/context-builder.ts:buildChatContext", + "func:packages/skill/src/diff-analyzer.ts:buildDiffContext", + "func:packages/skill/src/explain-builder.ts:buildExplainContext", + "func:packages/skill/src/onboard-builder.ts:buildOnboardingGuide" + ] + } + ] +} \ No newline at end of file diff --git a/packages/dashboard/src/App.tsx b/understand-anything-plugin/packages/dashboard/src/App.tsx similarity index 100% rename from packages/dashboard/src/App.tsx rename to understand-anything-plugin/packages/dashboard/src/App.tsx diff --git a/packages/dashboard/src/components/ChatPanel.tsx b/understand-anything-plugin/packages/dashboard/src/components/ChatPanel.tsx similarity index 100% rename from packages/dashboard/src/components/ChatPanel.tsx rename to understand-anything-plugin/packages/dashboard/src/components/ChatPanel.tsx diff --git a/packages/dashboard/src/components/CodeViewer.tsx b/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx similarity index 100% rename from packages/dashboard/src/components/CodeViewer.tsx rename to understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx diff --git a/packages/dashboard/src/components/CustomNode.tsx b/understand-anything-plugin/packages/dashboard/src/components/CustomNode.tsx similarity index 100% rename from packages/dashboard/src/components/CustomNode.tsx rename to understand-anything-plugin/packages/dashboard/src/components/CustomNode.tsx diff --git a/packages/dashboard/src/components/GraphView.tsx b/understand-anything-plugin/packages/dashboard/src/components/GraphView.tsx similarity index 100% rename from packages/dashboard/src/components/GraphView.tsx rename to understand-anything-plugin/packages/dashboard/src/components/GraphView.tsx diff --git a/packages/dashboard/src/components/LayerLegend.tsx b/understand-anything-plugin/packages/dashboard/src/components/LayerLegend.tsx similarity index 100% rename from packages/dashboard/src/components/LayerLegend.tsx rename to understand-anything-plugin/packages/dashboard/src/components/LayerLegend.tsx diff --git a/packages/dashboard/src/components/LearnPanel.tsx b/understand-anything-plugin/packages/dashboard/src/components/LearnPanel.tsx similarity index 100% rename from packages/dashboard/src/components/LearnPanel.tsx rename to understand-anything-plugin/packages/dashboard/src/components/LearnPanel.tsx diff --git a/packages/dashboard/src/components/NodeInfo.tsx b/understand-anything-plugin/packages/dashboard/src/components/NodeInfo.tsx similarity index 100% rename from packages/dashboard/src/components/NodeInfo.tsx rename to understand-anything-plugin/packages/dashboard/src/components/NodeInfo.tsx diff --git a/packages/dashboard/src/components/PersonaSelector.tsx b/understand-anything-plugin/packages/dashboard/src/components/PersonaSelector.tsx similarity index 100% rename from packages/dashboard/src/components/PersonaSelector.tsx rename to understand-anything-plugin/packages/dashboard/src/components/PersonaSelector.tsx diff --git a/packages/dashboard/src/components/SearchBar.tsx b/understand-anything-plugin/packages/dashboard/src/components/SearchBar.tsx similarity index 100% rename from packages/dashboard/src/components/SearchBar.tsx rename to understand-anything-plugin/packages/dashboard/src/components/SearchBar.tsx diff --git a/packages/dashboard/src/index.css b/understand-anything-plugin/packages/dashboard/src/index.css similarity index 100% rename from packages/dashboard/src/index.css rename to understand-anything-plugin/packages/dashboard/src/index.css diff --git a/packages/dashboard/src/main.tsx b/understand-anything-plugin/packages/dashboard/src/main.tsx similarity index 100% rename from packages/dashboard/src/main.tsx rename to understand-anything-plugin/packages/dashboard/src/main.tsx diff --git a/packages/dashboard/src/store.ts b/understand-anything-plugin/packages/dashboard/src/store.ts similarity index 100% rename from packages/dashboard/src/store.ts rename to understand-anything-plugin/packages/dashboard/src/store.ts diff --git a/packages/dashboard/src/utils/layout.ts b/understand-anything-plugin/packages/dashboard/src/utils/layout.ts similarity index 100% rename from packages/dashboard/src/utils/layout.ts rename to understand-anything-plugin/packages/dashboard/src/utils/layout.ts diff --git a/packages/dashboard/src/vite-env.d.ts b/understand-anything-plugin/packages/dashboard/src/vite-env.d.ts similarity index 100% rename from packages/dashboard/src/vite-env.d.ts rename to understand-anything-plugin/packages/dashboard/src/vite-env.d.ts diff --git a/packages/dashboard/tsconfig.app.json b/understand-anything-plugin/packages/dashboard/tsconfig.app.json similarity index 100% rename from packages/dashboard/tsconfig.app.json rename to understand-anything-plugin/packages/dashboard/tsconfig.app.json diff --git a/packages/dashboard/tsconfig.json b/understand-anything-plugin/packages/dashboard/tsconfig.json similarity index 100% rename from packages/dashboard/tsconfig.json rename to understand-anything-plugin/packages/dashboard/tsconfig.json diff --git a/packages/dashboard/vite.config.ts b/understand-anything-plugin/packages/dashboard/vite.config.ts similarity index 68% rename from packages/dashboard/vite.config.ts rename to understand-anything-plugin/packages/dashboard/vite.config.ts index 7e1f912..833d53b 100644 --- a/packages/dashboard/vite.config.ts +++ b/understand-anything-plugin/packages/dashboard/vite.config.ts @@ -13,10 +13,15 @@ export default defineConfig({ configureServer(server) { server.middlewares.use((req, res, next) => { if (req.url === "/knowledge-graph.json") { - // Look for .understand-anything/knowledge-graph.json up from cwd + // GRAPH_DIR env var points to the project being analyzed + // Falls back to monorepo root, then public/ (demo) + const graphDir = process.env.GRAPH_DIR; const candidates = [ + ...(graphDir + ? [path.resolve(graphDir, ".understand-anything/knowledge-graph.json")] + : []), path.resolve(process.cwd(), ".understand-anything/knowledge-graph.json"), - path.resolve(process.cwd(), "../../.understand-anything/knowledge-graph.json"), + path.resolve(process.cwd(), "../../../.understand-anything/knowledge-graph.json"), ]; for (const candidate of candidates) { if (fs.existsSync(candidate)) { diff --git a/packages/skill/skills/understand-chat/SKILL.md b/understand-anything-plugin/skills/understand-chat/SKILL.md similarity index 100% rename from packages/skill/skills/understand-chat/SKILL.md rename to understand-anything-plugin/skills/understand-chat/SKILL.md diff --git a/packages/skill/skills/understand-diff/SKILL.md b/understand-anything-plugin/skills/understand-diff/SKILL.md similarity index 100% rename from packages/skill/skills/understand-diff/SKILL.md rename to understand-anything-plugin/skills/understand-diff/SKILL.md diff --git a/packages/skill/skills/understand-explain/SKILL.md b/understand-anything-plugin/skills/understand-explain/SKILL.md similarity index 100% rename from packages/skill/skills/understand-explain/SKILL.md rename to understand-anything-plugin/skills/understand-explain/SKILL.md diff --git a/packages/skill/skills/understand-onboard/SKILL.md b/understand-anything-plugin/skills/understand-onboard/SKILL.md similarity index 100% rename from packages/skill/skills/understand-onboard/SKILL.md rename to understand-anything-plugin/skills/understand-onboard/SKILL.md diff --git a/packages/skill/skills/understand/SKILL.md b/understand-anything-plugin/skills/understand/SKILL.md similarity index 100% rename from packages/skill/skills/understand/SKILL.md rename to understand-anything-plugin/skills/understand/SKILL.md diff --git a/packages/skill/src/__tests__/context-builder.test.ts b/understand-anything-plugin/src/__tests__/context-builder.test.ts similarity index 100% rename from packages/skill/src/__tests__/context-builder.test.ts rename to understand-anything-plugin/src/__tests__/context-builder.test.ts diff --git a/packages/skill/src/__tests__/diff-analyzer.test.ts b/understand-anything-plugin/src/__tests__/diff-analyzer.test.ts similarity index 100% rename from packages/skill/src/__tests__/diff-analyzer.test.ts rename to understand-anything-plugin/src/__tests__/diff-analyzer.test.ts diff --git a/packages/skill/src/__tests__/explain-builder.test.ts b/understand-anything-plugin/src/__tests__/explain-builder.test.ts similarity index 100% rename from packages/skill/src/__tests__/explain-builder.test.ts rename to understand-anything-plugin/src/__tests__/explain-builder.test.ts diff --git a/packages/skill/src/__tests__/onboard-builder.test.ts b/understand-anything-plugin/src/__tests__/onboard-builder.test.ts similarity index 100% rename from packages/skill/src/__tests__/onboard-builder.test.ts rename to understand-anything-plugin/src/__tests__/onboard-builder.test.ts diff --git a/packages/skill/src/context-builder.ts b/understand-anything-plugin/src/context-builder.ts similarity index 100% rename from packages/skill/src/context-builder.ts rename to understand-anything-plugin/src/context-builder.ts diff --git a/packages/skill/src/diff-analyzer.ts b/understand-anything-plugin/src/diff-analyzer.ts similarity index 100% rename from packages/skill/src/diff-analyzer.ts rename to understand-anything-plugin/src/diff-analyzer.ts diff --git a/packages/skill/src/explain-builder.ts b/understand-anything-plugin/src/explain-builder.ts similarity index 100% rename from packages/skill/src/explain-builder.ts rename to understand-anything-plugin/src/explain-builder.ts diff --git a/packages/skill/src/index.ts b/understand-anything-plugin/src/index.ts similarity index 100% rename from packages/skill/src/index.ts rename to understand-anything-plugin/src/index.ts diff --git a/packages/skill/src/onboard-builder.ts b/understand-anything-plugin/src/onboard-builder.ts similarity index 100% rename from packages/skill/src/onboard-builder.ts rename to understand-anything-plugin/src/onboard-builder.ts diff --git a/packages/skill/src/understand-chat.ts b/understand-anything-plugin/src/understand-chat.ts similarity index 100% rename from packages/skill/src/understand-chat.ts rename to understand-anything-plugin/src/understand-chat.ts diff --git a/packages/core/tsconfig.json b/understand-anything-plugin/tsconfig.json similarity index 72% rename from packages/core/tsconfig.json rename to understand-anything-plugin/tsconfig.json index a086b14..e460062 100644 --- a/packages/core/tsconfig.json +++ b/understand-anything-plugin/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "../tsconfig.json", "compilerOptions": { "outDir": "dist", "rootDir": "src"